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

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

是否可以在不必使用C#DLL之前调用RegAsm的情况下执行此操作?

最佳答案

您可以将免注册COM与.NET COM组件一起使用-请参见here

另一种选择是使用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。后者可以在纯 native 应用程序中使用,如下所示:
// 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运行时加载到调用过程中(除非已经加载到调用过程中),并从 native 代码透明地分派(dispatch)到托管代码-所有魔术都是由C++/CLI编译器完成的。

关于c# - 如何从Win32进程调用.NET DLL?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1823466/

10-10 18:50
查看更多