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

时间:2009-12-01 01:20:47

标签: c# .net mixed-mode

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

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

是否可以在不使用C#DLL之前调用RegAsm来执行此操作?

2 个答案:

答案 0 :(得分:11)

您可以在.NET COM组件中使用免注册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。后者可以在纯本机应用程序中使用,如下所示:

// 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编译器完成的。

答案 1 :(得分:7)

有两种选择。

首先,您可以使用Registration Free COM Interop

其次,您可以使用CLR Hosting APIs直接托管CLR,然后加载程序集。这没有COM。