如何从Win32进程调用.NET DLL?

8
当使用.NET DLL从Win32进程中调用时,有哪些选项? 我需要从Win32进程中使用一个C# DLL。
我现在有一个可能的解决方案,需要将C# DLL添加到GAC(使用RegAsm.exe),然后通过COM包装调用C# DLL。 但是这个解决方案比较重。它要求将.NET DLL添加到所有应该运行此Win32进程的机器上的GAC
是否可以在不必调用RegAsm之前就能使用C# DLL?

不需要使用Regasm.exe /codebase选项将其放在GAC中。 - Hans Passant
2个回答

11
你可以在.NET COM组件中使用无需注册的COM - 请参见此处
另一个选择是使用C++/CLI作为桥梁。人们通常熟悉使用它来包装未管理的API以暴露给托管代码,但实际上它可以双向工作 - 可以使用/clr编译,然后产生一个带有普通未管理导出的.dll程序集,可以像往常一样从未管理的代码中调用。这里是一个非常简单的示例,以这种方式公开System::String::ToUpper
// compile with cl.exe /clr /LD wrapper.cpp ole32.lib

#include <windows.h>

__declspec(dllexport)
wchar_t* ToUpper(const wchar_t* wcs)
{
    System::String^ s = gcnew System::String(wcs);
    array<wchar_t>^ chars = s->ToUpper()->ToCharArray();

    size_t size = chars->Length * 2;
    wchar_t* dst = (wchar_t*)CoTaskMemAlloc(size + 2);
    pin_ptr<wchar_t> src = &chars[0];
    memcpy(dst, src, size);
    dst[chars->Length] = 0;
    return dst;
}

这将生成一个混合托管/非托管程序集wrapper.dll和一个导出库wrapper.lib。后者可在纯本机应用程序中使用,方法如下:

// compile with cl.exe test.cpp ole32.lib wrapper.lib
// note, no /clr

#include <stdio.h>
#include <windows.h>

wchar_t* ToUpper(const wchar_t* wcs);

int main()
{
    wchar_t* s = ToUpper(L"foo");  
    wprintf(L"%s", s);
    CoTaskMemFree(s);
}

实际上,它将在调用进程中加载CLR运行时(除非已经加载了该运行时),并从本地代码无缝地分派到托管代码 - 所有的魔法都由C++ / CLI编译器完成。


这听起来非常不错,非常感谢。我会探索这个解决方案。 - Zoran Simic
*here*指向为注册自由激活配置基于.NET的组件。...以防微软决定(重新)移除此内容... - Wolf

7

1
CLR托管API可以通过利用C++/CLI间接使用 - 请参阅我的答案更新。 - Pavel Minaev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接