gpt4 book ai didi

c# - 使用 C/C++ 编写 DLL 以实现 .Net 互操作性

转载 作者:行者123 更新时间:2023-11-30 18:43:50 28 4
gpt4 key购买 nike

在我的 C# 应用程序中,我想用 C 编写一部分代码。我计划编写一个 DLL 女巫,可以与 .Net 互操作。我该怎么做?

最佳答案

基本上有三种正确的方法:

  • 使用 C++/CLI。如果此 DLL 仅供 .NET 使用,这是最佳方式。
  • 使用“extern "C"”兼容的 API,例如 Windows API 本身。这是最便携的,但对于您的调用者来说不如使用类模型来表示您的对象方便。
    • 如果您真的打算用 ANSI C(而不是 C++)编写,这是最佳选择。
    • 对于此路径,您将函数编写为 extern "C"returntype __stdcall __declspec(dllexport) func(params) { ... }
    • 您还应该使用“调用者提供缓冲区”内存模型,而不是返回在您的库中分配的缓冲区。在确实需要为内部状态分配内存的情况下,调用者应将其视为不透明句柄,并且应为调用者提供访问器函数以提取数据。在任何情况下都不应期望调用者释放在您的库中分配的内存,但是调用者可以要求库进行释放。
  • 使用 COM 或类似 COM 的 API。在这里,您返回(通常通过 out 参数)一个指向接口(interface)的指针,该接口(interface)是一个具有纯虚函数、没有非虚函数且没有数据的类。
    • 实现是在从这个抽象接口(interface)派生的具体类中,它们可以有大量的数据和辅助函数,因为这不会影响二进制接口(interface)。
    • 这比库中的工作要多得多,但非常便携且易于消费者使用。

有一件事绝对不能做:

  • 在 C++ 类上使用 __declspec(dllexport)

编辑:我还想解释选项 #2 的一些良好实践,这将最大限度地提高可移植性,并使 native C/C++ 部分也可从非托管应用程序中使用。

您可以使用宏来简化此操作,通常的做法是:

在你的头文件中,所有的函数声明看起来像

MYPROJECTAPI(returntype) PublicFunc(params);

在你的项目中,定义是

#define MYPROJECTAPI(returntype) \
extern "C" returntype __stdcall __declspec(dllexport)

在消费者项目中

#define MYPROJECTAPI(returntype) \
extern "C" returntype __stdcall __declspec(dllimport)

然后您可以为其他不使用 __declspec 的编译器(例如 gcc)定义不同的宏。

完整的解决方案看起来像(在公共(public)头文件 myproject.h 中):

#if _WIN32
# if BUILDMYPROJECT
# define MYPROJECTAPI(returntype) \
extern "C" returntype __stdcall __declspec(dllexport)
# else
# define MYPROJECTAPI(returntype) \
extern "C" returntype __stdcall __declspec(dllimport)
# endif
#else
# define MYPROJECTAPI(returntype) extern "C" returntype
#endif

然后您的 Visual C++ 项目将导致在构建 myproject.dll 时定义 BUILDMYPROJECT

关于c# - 使用 C/C++ 编写 DLL 以实现 .Net 互操作性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3760155/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com