【发布时间】:2010-09-18 12:35:21
【问题描述】:
我想从非托管 C++ 调用我的 .NET 代码。我的进程入口点是基于 .NET 的,所以我不必担心托管 CLR。我知道它可以使用 .NET 对象的 COM 包装器来完成,但我想访问托管类的各个静态方法,所以 COM 不是我最短/最简单的路线。
【问题讨论】:
标签: .net c++-cli interop clr unmanaged
我想从非托管 C++ 调用我的 .NET 代码。我的进程入口点是基于 .NET 的,所以我不必担心托管 CLR。我知道它可以使用 .NET 对象的 COM 包装器来完成,但我想访问托管类的各个静态方法,所以 COM 不是我最短/最简单的路线。
【问题讨论】:
标签: .net c++-cli interop clr unmanaged
看看这个解决方案: https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports 该解决方案允许通过使用 [DllExport] 属性(与 P/Invoke DllImport 相对)装饰您的函数来从 C 调用 C# 函数。
示例:
C#代码
class Test
{
[DllExport("add", CallingConvention = CallingConvention.StdCall)]
public static int Add(int left, int right)
{
return left + right;
}
}
C 代码:
extern "C" int add(int, int);
int main()
{
int z = add(5,10);
printf("The solution is found!!! Z is %i",z);
return 0;
}
输出:
The solution is found!!! Z is 15
更新:cmets中有一个问题和一个很好的答案:
如何在非托管项目中包含 dll?
您必须链接到编译 C# 代码时生成的 .lib 文件 (https://msdn.microsoft.com/en-us/library/ba1z7822.aspx?f=255&MSPPError=-2147217396)
【讨论】:
假设您谈论的是真正的非托管代码 - 不仅仅是在使用 /clr 编译的混合模式程序集中运行的本机 C++ - 最简单的方法是在 C++/CLI 中为您的 .NET 代码创建一个包装器。然后,您只需用 __declspec(dllexport) 标记即可导出 C++/CLI 方法。
或者,如果您可以控制非托管代码的调用,则可以将函数指针编组到您的 .NET 方法并将它们传递给非托管代码。
【讨论】:
我相信您正在寻找反向 PInvoke。如果你用谷歌搜索反向 pinvoke,你会得到很多有用的条目。我认为以下有一个很好的快速而肮脏的例子。
【讨论】:
您的调用代码是启用了/clr 的C++。正确的?
如果是,那么您可以简单地使用 using 语句在您的代码中使用您的 .NET dll。比如:
#using <Mydll.dll>
然后您可以简单地创建托管类的对象,例如:
MyNameSpace::MyClass^ obj = new MyNameSpace::MyClass();
如果你想让这个 obj 成为你的类的数据成员,那么使用 gcroot 是要走的路。
【讨论】:
在这里找到好方法Using C# from native C++ with the help of C++/CLI 集成到不同的解决方案后也发现了这些变化:
其他IncludeDirectories ...YahooAPIWrapper
其他依赖项 ...YahooAPIWrapper.lib
与这两个项目的关系,能够在最后一个 DLL 中通过线程打开 C# 表单并从本机 C++ 发送信息,只需要 ...APIWrapper.h 包括 - 应该做得更好,但可以工作 ;-)
public YahooAPI()
{
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
ShowForm();
}).Start();
}
private static Form1 form = null;
public static void ShowForm()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
form = new Form1();
Application.Run(form);
}
public void SendValues(bool[] values)
{
if (form != null && form.ready) ...
}
当表单初始化完成时,ready 是我的 bool 成员集
【讨论】: