从Win32进程使用.NET DLL有什么选择? 我需要从Win32进程中基本使用C#DLL。如何从Win32进程调用.NET DLL?
我现在有一个可能的解决方案,需要将C#DLL添加到GAC(使用RegAsm.exe),然后通过COM打包调用调用C#DLL。 但是这个解决方案相当繁重。它要求将.NET DLL添加到应该运行此Win32进程的所有机器上的GAC。
在使用C#DLL之前,无需调用RegAsm
就可以做到这一点吗?
从Win32进程使用.NET DLL有什么选择? 我需要从Win32进程中基本使用C#DLL。如何从Win32进程调用.NET 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
。后者可以在纯原生应用程序中使用如下:
// 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-02 19:08:08
*'here' *指向[配置免注册激活的基于.NET的组件](https://msdn.microsoft.com/en-us/library/eew13bza(VS.71) .aspx)...如果MS决定(重新)移动此... – Wolf 2017-01-10 14:45:46
有两种选择。您可以使用Registration Free COM Interop。
其次,您可以使用CLR Hosting APIs来直接托管CLR并加载程序集。这没有COM的作品。
CLR托管API可通过利用C++/CLI间接使用 - 请参阅我的答案的更新。 – 2009-12-01 01:56:24
它不必在GAC中使用Regasm.exe/codebase选项。 – 2009-12-01 02:52:12