在非托管程序中托管CLR时从内存加载程序集

4
我通过丰富的文档成功地将CLR托管在非托管程序中。然而,在托管CLR时,似乎只能从硬盘加载程序集。当运行托管应用程序时,可以通过调用Assembly.Load()从内存中加载程序集。
有没有办法从内存中执行托管CLR中的程序集呢?类似于:
1. 将托管程序集写入内存 2. 初始化CLR 3. 启动CLR 4. 从内存中执行托管程序集 5. 等待托管程序集返回 6. 停止CLR
我已经在网络和MSDN上搜索了几个小时,但是找不到解决这个问题的方法!我想到的一个变通方法涉及另一个调用Assembly.Load()的程序集,但我担心这可能过于复杂。
提前感谢您提供任何提示或建议!

你有任何错误吗?有没有演示问题的示例代码? - Simon Mourier
@SimonMourier,我添加了悬赏是因为许多人在实现.NET许可系统时经常需要这个功能。 - Samuel Allan
1个回答

7
我建议您从这个示例开始:C++ app hosts CLR 4 and invokes .NET assembly (CppHostCLR),这个示例几乎满足您的需求。唯一缺少的部分是它没有从内存加载程序集,而是使用了一个文件。

所以您需要做的就是替换以下代码行(在RuntimeHostV4.cpp中):

// Load the .NET assembly. 
wprintf(L"Load the assembly %s\n", pszAssemblyName); 
hr = spDefaultAppDomain->Load_2(bstrAssemblyName, &spAssembly); 
if (FAILED(hr)) 
{ 
    wprintf(L"Failed to load the assembly w/hr 0x%08lx\n", hr); 
    goto Cleanup; 
} 

请使用以下代码行代替此方法:_AppDomain.Load 方法(Byte[])
// let's suppose I have a LPBYTE (pointer to byte array) and an ULONG (int32) value
// that describe the buffer that contains an assembly bytes.
LPBYTE buffer = <my buffer>;
ULONG size = <my buffer size>;

// let's create an OLEAUT's SAFEARRAY of BYTEs and copy the buffer into it
// TODO: add some error checking here (mostly for out of memory errors)
SAFEARRAYBOUND bounds = { size, 0 };
SAFEARRAY *psa = SafeArrayCreate(VT_UI1, 1, &bounds);
void* data;
SafeArrayAccessData(psa, &data);
CopyMemory(data, buffer, size);
SafeArrayUnaccessData(psa);

hr = spDefaultAppDomain->Load_3(psa, &spAssembly);
if (FAILED(hr))
{
    wprintf(L"Failed to load the assembly w/hr 0x%08lx\n", hr);
    goto Cleanup;
}
SafeArrayDestroy(psa); // don't forget to destroy

很棒的答案,可惜只有很少的人做出了贡献。 - Samuel Allan
恭喜你获得奖励! - Samuel Allan

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