在C ++(Win32应用程序)中使用C#类时,EEFileLoadException
时间:2020-03-06 14:22:01 来源:igfitidea点击:
出于部署原因,我尝试使用IJW将Cassembly封装在C ++中,而不是使用COM可调用包装器。
我已经在其他项目上做到了,但是在这个项目上,我得到了EEFileLoadException。任何帮助,将不胜感激!
托管的C ++包装器代码(在DLL中):
extern "C" __declspec(dllexport) IMyObject* CreateMyObject(void)
{
//this class references c# in the constructor
return new CMyWrapper( );
}
extern "C" __declspec(dllexport) void DeleteMyObject(IMyObject* pConfigFile)
{
delete pConfigFile;
}
extern "C" __declspec(dllexport) void TestFunction(void)
{
::MessageBox(NULL, _T("My Message Box"), _T("Test"), MB_OK);
}
测试代码(这是一个EXE):
typedef void* (*CreateObjectPtr)();
typedef void (*TestFunctionPtr)();
int _tmain testwrapper(int argc, TCHAR* argv[], TCHAR* envp[])
{
HMODULE hModule = ::LoadLibrary(_T("MyWrapper"));
_ASSERT(hModule != NULL);
PVOID pFunc1 = ::GetProcAddress(hModule, "TestFunction");
_ASSERT(pFunc1 != NULL);
TestFunctionPtr pTest = (TestFunctionPtr)pFunc1;
PVOID pFunc2 = ::GetProcAddress(hModule, "CreateMyObject");
_ASSERT(pFunc2 != NULL);
CreateObjectPtr pCreateObjectFunc = (CreateObjectPtr)pFunc2;
(*pTest)(); //this successfully pops up a message box
(*pCreateObjectFunc)(); //this tosses an EEFileLoadException
return 0;
}
对于其价值,事件日志报告以下内容:
.NET运行时版本2.0.50727.143
致命执行引擎错误(79F97075)(80131506)
不幸的是,Microsoft没有关于该错误的信息。
解决方案
第一个问题是确保将"调试器"类型设置为"混合"。然后,我们将获得有用的异常。
问题出在DLL所在的位置。
- c:\ dlls \ managed.dll
- c:\ dlls \ wrapper.dll
- c:\ exe \ my.exe
我通过将Managed.dll复制到c:\ exe来确认这一点,并且工作正常。显然,CLR不会在非托管DLL的路径中查找托管DLL,而只会在可执行文件所在的位置查找托管DLL。 (或者在GAC中)。
由于不值得讨论的原因,这就是我需要的结构,这意味着我需要让CLR亲自找到托管的dll。参见下面的代码:
AssemblyResolver.h:
/// <summary>
/// Summary for AssemblyResolver
/// </summary>
public ref class AssemblyResolver
{
public:
static Assembly^ MyResolveEventHandler( Object^ sender, ResolveEventArgs^ args )
{
Console::WriteLine( "Resolving..." );
Assembly^ thisAssembly = Assembly::GetExecutingAssembly();
String^ thisPath = thisAssembly->Location;
String^ directory = Path::GetDirectoryName(thisPath);
String^ pathToManagedAssembly = Path::Combine(directory, "managed.dll");
Assembly^ newAssembly = Assembly::LoadFile(pathToManagedAssembly);
return newAssembly;
}
};
Wrapper.cpp:
#include "AssemblyResolver.h"
extern "C" __declspec(dllexport) IMyObject* CreateMyObject(void)
{
try
{
AppDomain^ currentDomain = AppDomain::CurrentDomain;
currentDomain->AssemblyResolve += gcnew ResolveEventHandler( AssemblyResolver::MyResolveEventHandler );
return new CMyWrapper( );
}
catch(System::Exception^ e)
{
System::Console::WriteLine(e->Message);
return NULL;
}
}

