8

在 Win32 进程中使用 .NET DLL 时有哪些选择?我需要基本上使用 Win32 进程中的 C# DLL。

我现在有一个可能的解决方案,需要将 C# DLL 添加到 GAC(使用 RegAsm.exe),然后通过 COM 包装调用调用 C# DLL。但是,该解决方案非常繁重。它要求将 .NET DLL 添加到应该运行此 Win32 进程的所有计算机上的GAC 。

RegAsm在能够使用 C# DLL 之前不必调用就可以做到这一点吗?

4

2 回答 2

11

您可以将免注册 COM 与 .NET 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 编译器完成的。

于 2009-12-01T01:26:06.310 回答
7

有两种选择。

首先,您可以使用免费注册 COM 互操作

其次,您可以使用CLR 托管 API直接托管 CLR,并加载程序集。这在没有 COM 的情况下有效。

于 2009-12-01T01:50:58.737 回答