如何使托管代码中的 c++ dll 中的其他 dll 可以使用方法?

Posted

技术标签:

【中文标题】如何使托管代码中的 c++ dll 中的其他 dll 可以使用方法?【英文标题】:How do you make a method avaible to other dlls in a c++ dll in managed code? 【发布时间】:2011-09-21 08:35:40 【问题描述】:

第一段代码是我正在处理的示例,在将其更改为第二个示例后,它适用于 __declspec(dllexport),它给出了 __declspec(dllexport) 不能应用于具有 __clrcall 调用的函数惯例。删除那段代码确实使 dll 编译但该方法对目标 dll 不可用。此外,当我使用 PE Explorer 查看 DLL 时,没有导出方法。 __declspec(dllexport) 是否有托管变体?

extern "C" __declspec(dllexport) int UserInstruction (HWND hWnd,
                              HINSTANCE hInst,
                              double FAR *Function, 
                              char FAR *Str1,
                              char FAR *Str2)

       strcpy(Str1, "TEST FUNCTION");
       return (TRUE);



extern "C" __declspec(dllexport) int UserInstruction (IntPtr hWnd, IntPtr hInst, double *Function, char *Str1, char *Str2)

    Str1 = "TEST FUNCTION";
    return (true);

【问题讨论】:

Check here the answer. @Naszta 在那个答案之后,一切都建立了,但 PE Explorer 仍然看不到任何导出的方法。同样在尝试运行目标 exe 时,它​​仍然抱怨它无法访问 UserInstruction。该 exe 是在名为 PReS 的东西中制作的,无法更改,并且正在寻找要导出的 UserInstruction,就像它不受管理一样。 链接的答案不会生成非托管导出,已添加答案。 【参考方案1】:

C++/CLI 编译器支持导出托管函数。它会自动生成一个 thunk,在必要时加载和初始化 CLR,以便可以执行托管代码。当心开销。但是,您不能对函数参数使用任何托管类型。 IntPtr 在您的情况下。这没有任何意义,调用您的函数的非托管代码不会使用托管类型。

您必须自己编组它们。这不是问题,这些是指针,因此您可以简单地转换为 IntPtr:

extern "C" __declspec(dllexport) 
int __stdcall UserInstruction (HWND hWnd, HINSTANCE hInst, double FAR *Function, char FAR *Str1, char FAR *Str2)

    IntPtr windowPtr = (IntPtr)hWnd;
    IntPtr instancePtr = (IntPtr)hInst;
    // etc..

明确选择调用约定总是一个好主意。出于这个原因,我添加了 __stdcall,这是导出 DLL 函数中最常见的一种。

【讨论】:

那么问题是出现了错误 C2065: 'HWND' : undeclared identifier。此类必须将数据从 PReS 传递到 C#(PReS 无法与 c# 对话) 您必须#include <windows.h> 才能使用 Windows 类型。

以上是关于如何使托管代码中的 c++ dll 中的其他 dll 可以使用方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 C# 导入和使用非托管 C++ 类?

C# .Net 4.0 应用程序中托管的 C++ ActiveX 控件中的 Xml.Serializer 非法强制转换异常

如何调试 DLL 中的代码

使用 DLL 中的 COM 对象,无需注册

本机代码中的托管 dll(通过 com)。它是在进程中还是在进程 com 服务器中?

本机代码中的托管 dll(通过 com)。它是在进程中还是在进程 com 服务器中?