20

我想从非托管 C++ 调用我的 .NET 代码。我的进程入口点是基于 .NET 的,所以我不必担心托管 CLR。我知道它可以使用 .NET 对象的 COM 包装器来完成,但我想访问托管类的各个静态方法,所以 COM 不是我最短/最简单的路线。

4

6 回答 6

23

查看此解决方案: 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

更新:评论中有一个问题和一个很好的答案:

如何在非托管项目中包含 dll?

您必须链接到编译 C# 代码时生成的 .lib 文件(https://msdn.microsoft.com/en-us/library/ba1z7822.aspx?f=255&MSPPError=-2147217396

于 2011-07-22T20:09:12.297 回答
7

看看GCHandle类和 gcroot 关键字,它提供了一个围绕 GCHandle 的类型安全、模板化的包装器。

您可以使用它们在本机代码中保存对 CLR 对象(或装箱值)的引用。

MSDN这里有一个基本教程。

于 2008-10-22T11:44:32.503 回答
6

假设您正在谈论真正的非托管代码 - 不仅仅是在使用 /clr 编译的混合模式程序集中运行的本机 C++ - 最简单的方法是在 C++/CLI 中为您的 .NET 代码创建一个包装器。然后,您可以通过使用 __declspec(dllexport) 标记它们来导出 C++/CLI 方法。

或者,如果您可以控制非托管代码的调用,则可以将函数指针编组到您的 .NET 方法并将它们传递给非托管代码。

于 2008-10-22T11:27:16.657 回答
4

我相信您正在寻找反向 PInvoke。如果你用谷歌搜索反向 pinvoke,你会得到很多有用的条目。我认为以下有一个很好的快速而肮脏的例子。

PInvoke-反向 PInvoke 和 __stdcall - __cdecl

于 2008-10-30T17:27:08.617 回答
1

您的调用代码是/clr启用的 C++。对?

如果是,那么您可以简单地使用 using 语句在代码中使用您的 .NET dll。就像是:

#using <Mydll.dll>

然后您可以简单地制作托管类的对象,例如:

MyNameSpace::MyClass^ obj = new MyNameSpace::MyClass();

如果你想让这个 obj 成为你的类的数据成员,那么使用 gcroot 是要走的路。

于 2008-10-22T12:04:31.743 回答
1

在集成到不同的解决方案后,在 C++/CLI 的帮助下,在本机 C++ 中使用 C#,还发现了这些变化:

附加的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 成员

于 2021-08-07T12:56:39.957 回答