出于部署原因,我试图使用IJW在C++中包装C#程序集,而不是使用COM Callable Wrapper.
我已经在其他项目上完成了,但是在这个项目上,我得到了一个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:\ dll文件\ managed.dll
C:\ dll文件\ wrapper.dll
C:\ EXE\my.exe
我通过将managed.dll复制到c:\ exe来确认这一点,并且它没有问题.显然,CLR不会在非托管DLL的路径中查找托管DLL,只会查找可执行文件所在的DLL.(或在GAC中).
由于不值得进入的原因,这就是我需要的结构,这意味着我需要让CLR找到托管dll.见下面的代码:
AssemblyResolver.h:
////// Summary for AssemblyResolver /// 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; } }
第一个问题是确保Debugger类型设置为mixed.然后你得到有用的例外.