使用C ++ DLL与C ++ / CLI包装器 [英] Using C++ DLL vs C++/CLI wrapper

查看:58
本文介绍了使用C ++ DLL与C ++ / CLI包装器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在C#应用程序中使用OpenCL。在C#应用程序中查看使用C ++代码的不同方法,我找到了这两个解决方案:

1.使用我的C ++函数创建一个DLL:

I need to use OpenCL in my C# application. Looking into different ways of using C++ code in C# application I found these two solutions:
1. Make a DLL with my C++ functions like this:

extern "C++"
{
   __declspec(dllexport) void foo(){}
}


然后在我的C#代码中使用它们,如下所示:

And then use them in my C# code like this:

using System;
using System.Runtime.InteropServices;

class HelloWorld
{
    [DllImport("My.dll")]
    public static extern void foo ();
}


这种方法看起来非常简单,虽然我还在考虑使用更复杂的对象作为参数(我可能需要传递大量的2d点数和matrices)。



2.另一种选择是使用我的C ++代码制作DLL,然后为它编写C ++ / CLI包装,然后在我的C#代码中使用它。看起来不那么简单,因为它在我的C ++和C#代码之间添加了一个额外的层,并且还需要
了解C ++ / CLI。



有人可以解释一下我这两个选项?哪一个能提供更好的性能?两者有什么限制?




This approach seems pretty straightforward, though I'm yet too look into using more complex objects as parameters (I am likely to need to pass large arrays of 2d points and matrices).

2. Another option is involves making a DLL with my C++ code, then writing a C++/CLI wrapper for it and then using it in my C# code. Seems less straightforward, as it add an extra layer between my C++ and C# code and would also require the knowledge of C++/CLI.

Can someone explain me these two options? Which one would give better perfomance? What are the limitations of both?


推荐答案

1。你需要使用extern"C"。在你的DLL中。这会将DLL暴露为C导出而不会出现C ++的名称错误。结果函数就像_foo。在DllImport中,您需要指定EntryPoint
属性并相应地设置方法名称。

1. You'd need to use extern "C" in your DLL. This would expose the DLL as a C export without the name mangling that C++ does. The resulting function would be something like _foo. In your DllImport you'd then need to specify the EntryPoint attribute and set the method name accordingly.

如果您需要访问几个函数,这是可行的方法在C ++中。最大的限制是你不能来回传递物体。这包括来自STL,C ++字符串甚至其他C ++类的内容。所有这些
都必须作为指针进行编组,这会产生令人困惑的函数接口,甚至可能导致损坏。

This is the way to go if you need access to a couple of functions in C++. The biggest restriction is that you cannot pass objects back and forth. This includes things from the STL, C++ strings or even other C++ classes. All these would have to be marshalled as pointers which makes for a confusing function interface and may even cause corruption.

2。如果你正在处理C ++类,C ++ / CLI是更好的方法。您无法使用extern"C"来轻松传递类实例。这样简单地将它包装在C ++ / CLI中是最有意义的。

2. C++/CLI is the better approach if you're dealing with C++ classes. You cannot easily pass class instances around using the extern "C" approach so simply wrapping it in C++/CLI makes the most sense.

这种方法的最大好处是你只能暴露你真正需要的部分,你可以存储本机的东西。字段,以避免与托管代码共享它们。如果您将大量对象
作为字段处理,这一点尤为重要。缺点是你需要暴露的任何对象仍然需要是一个指针,或者你也必须将它们转换为C ++ / CLI。取决于你需要做多少工作决定它的努力程度。

The biggest benefit of this approach is that you can expose only the parts you actually need and you can store the native stuff in fields to avoid having to share them with managed code. This is especially important if you are dealing with lots of objects as fields. The disadvantage is that any objects that you do need to expose still either needs to be a pointer or you have to convert them to C++/CLI as well. Depending upon how much of that you have to do determines how big an effort it is.

有很多C ++函数跟随"对象"。语义,但实际上不是C ++类。例如,Windows中的标准HFILE遵循这种方法。虽然不是C ++类,但您需要"初始化"。它,
跟踪句柄并最终关闭它。所有这一切都尖叫着编写一个C#类来包装它。这就是很多早期框架的工作方式。但最终这个代码仍然是extern"C"。因为它是Win32公开的方式。

There are many C++ functions that follow "object" semantics but aren't actually C++ classes. For example the standard HFILE in Windows follows this approach. While not a C++ class you do need to "initialize" it, track the handle and eventually close it. All of this screams out writing a C# class to wrap it. That is how a lot of the early framework worked. But ultimately this code is still extern "C" because that is how it is exposed by Win32.

至于性能,我不知道你可以不经测试就知道。我怀疑(1)加载DLL后更快,因为你只是来回编组数据。但是,如果你正在包装其中一个"对象"语义函数然后
你将每次来回传递类似的数据。在这种情况下,(1)可能开始增加开销,而不仅仅是让C ++ / CLI在内部保留一个不需要来回传递的字段。如果它是"对象",语义然后
无论如何你正在写一个C#类,所以用C ++ / CLI编写类可能更有意义。这将允许您在单个代码库中混合使用C ++ /托管代码,而无需显式编组。生成的代码将处理它。

As for performance I don't know that you can know without testing. I suspect that (1) is faster once the DLL is loaded simply because you're just marshaling data back and forth. But if you're wrapping one of those "object" semantic functions then you're going to be passing similar data back and forth each time. In this case (1) may start adding overhead vs just having C++/CLI keep a field internally that doesn't need to be passed back and forth. And if it is "object" semantics then you're writing a C# class anyway so it probably makes more sense to write the class in C++/CLI. That will allow you to mix C++/managed code in a single code base without the need for explicit marshalling. The generated code will handle it.

至于学习曲线,是的,你必须知道C ++ / CLI,但它实际上不是太多的C ++代码或任何#现有的"扩展"添加到C ++。并且可能你会在
C ++ / CLI中创建一个独立的项目来包装你想要暴露的部分,所以每个人都不一定需要理解它,除非他们在界面代码中改变了一些东西。

As for the learning curve, yes, you have to know C++/CLI but it really isn't too much of a stretch from C++ code or any # of the existing "extensions" added to C++. And presumably you'd be creating a standalone project in C++/CLI to wrap only the parts you want exposed so everybody doesn't necessarily need to understand it unless they change something in the interface code.

我现在要抛弃一个选项3.

I going to throw out an option 3 now.

3。使用包装openCL的现有托管库。已有一些可用。除非你真的需要优化它或者使用第三方代码存在问题,否则让其他人为你解决问题总是一个不错的选择。

3. Use an existing managed library that wraps openCL. There are already some available. Unless you really need to optimize it or have an issue with using third party code then letting someone else solve the problem for you is always a good choice.

Michael Taylor

http://www.michaeltaylorp3.net

Michael Taylor
http://www.michaeltaylorp3.net


这篇关于使用C ++ DLL与C ++ / CLI包装器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆