.net 如何从非托管代码调用托管代码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/225277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to call managed code from unmanaged code?
提问by Hanan
I want to call my .NET code from unmanaged C++. My process entrypoint is .NET based, so I don't have to worry about hosting the CLR. I know it can be done using COM wrappers for .NET objects, but I would like to access individual static methods of managed classes, so COM isn't my shortest/easiest route.
我想从非托管 C++ 调用我的 .NET 代码。我的流程入口点是基于 .NET 的,所以我不必担心托管 CLR。我知道它可以使用 .NET 对象的 COM 包装器来完成,但我想访问托管类的各个静态方法,所以 COM 不是我最短/最简单的路线。
采纳答案by Rasmus Faber
Assuming you are talking about real unmanaged code - not just native C++ running in a mixed-mode assembly compiled with /clr - the easiest way is to create a wrapper to your .NET code in C++/CLI. You can then export the C++/CLI methods by just marking them with __declspec(dllexport).
假设您正在谈论真正的非托管代码 - 不仅仅是在使用 /clr 编译的混合模式程序集中运行的本机 C++ - 最简单的方法是在 C++/CLI 中为您的 .NET 代码创建包装器。然后,您只需使用 __declspec(dllexport) 标记即可导出 C++/CLI 方法。
Alternatively, if you have control over the invocation of the unmanaged code, you can marshal function-pointers to your .NET methods and pass them to the unmanaged code.
或者,如果您可以控制非托管代码的调用,则可以将函数指针编组到 .NET 方法并将它们传递给非托管代码。
回答by MajesticRa
Look at this solution: https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexportsThe solution allows to call C# function from C by decorating your function with [DllExport] attribute (opposite of P/Invoke DllImport).
看看这个解决方案:https: //sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports该解决方案允许通过使用 [DllExport] 属性装饰您的函数(与 P/Invoke DllImport 相反)从 C 调用 C# 函数.
Exmaple:
例子:
C# code
C# 代码
class Test
{
[DllExport("add", CallingConvention = CallingConvention.StdCall)]
public static int Add(int left, int right)
{
return left + right;
}
}
C code:
代码:
extern "C" int add(int, int);
int main()
{
int z = add(5,10);
printf("The solution is found!!! Z is %i",z);
return 0;
}
Output:
输出:
The solution is found!!! Z is 15
Update: There is a question and a good answer in comments:
更新:评论中有一个问题和一个很好的答案:
How do I include the dll in the unmanaged project?
如何在非托管项目中包含 dll?
You have to link to the .lib file that is generated upon compiling your C# code (https://msdn.microsoft.com/en-us/library/ba1z7822.aspx?f=255&MSPPError=-2147217396)
您必须链接到编译 C# 代码时生成的 .lib 文件(https://msdn.microsoft.com/en-us/library/ba1z7822.aspx?f=255&MSPPError=-2147217396)
回答by Stu Mackellar
Take a look at the GCHandleclass and the gcroot keyword, which provides a typesafe, templated wrapper around GCHandle.
查看GCHandle类和 gcroot 关键字,它提供了一个类型安全的、模板化的 GCHandle 包装器。
You can use these to hold a reference to a CLR object (or a boxed value) in native code.
您可以使用它们在本机代码中保存对 CLR 对象(或装箱值)的引用。
MSDN has a basic tutorial here.
MSDN 有一个基本教程here。
回答by JaredPar
I believe you are looking for Reverse PInvoke. If you google for reverse pinvoke you'll get a lot of helpful entries. I think the following has a good quick and dirty example.
我相信您正在寻找反向 PInvoke。如果你用谷歌搜索反向 pinvoke,你会得到很多有用的条目。我认为下面有一个很好的快速和肮脏的例子。
回答by Aamir
Your calling code is C++ with /clrenabled. Right?
您的调用代码是/clr启用的C++ 。对?
If yes, then you can simply use the using statement to use your .NET dll in your code. Something like:
如果是,那么您可以简单地使用 using 语句在您的代码中使用您的 .NET dll。就像是:
#using <Mydll.dll>
and then you can simply make the objects of your managed classes like:
然后您可以简单地制作托管类的对象,例如:
MyNameSpace::MyClass^ obj = new MyNameSpace::MyClass();
If you want to make this obj a data member of your class the using gcroot is the way to go.
如果你想让这个 obj 成为你的类的数据成员,使用 gcroot 是要走的路。

