用C使用C#类时EEFileLoadException ++(Win32的应用程序) [英] EEFileLoadException when using C# classes in C++(win32 app)

查看:2057
本文介绍了用C使用C#类时EEFileLoadException ++(Win32的应用程序)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关部署的原因,我想使用IJW用C来包装一个C#程序集++而不是使用COM可调用包装的。



我已经做到了在其他项目上,但是这一次,我得到一个EEFileLoadException。 !任何帮助,将不胜感激。



托管C ++包装代码(这是一个DLL):

 的externC__declspec(dllexport)的IMyObject * CreateMyObject(无效)
{
//这个类引用C#构造函数
返回新CMyWrapper();
}

的externC__declspec(dllexport)的无效​​DeleteMyObject(IMyObject * pConfigFile)
{
删除pConfigFile;
}

的externC__declspec(dllexport)的无效​​TestFunction(无效)
{
::的MessageBox(NULL,_T(我的消息框), _T(测试),MB_OK);
}



测试代码(这是一个EXE):

 的typedef无效*(* CreateObjectPtr)(); 
无效的typedef(* TestFunctionPtr)();

INT _tmain testwrapper(INT ARGC,TCHAR *的argv [],TCHAR * envp [])
{
HMODULE HMODULE = ::调用LoadLibrary(_T(MyWrapper)) ;
_assert(HMODULE!= NULL);

PVOID pFunc1 = :: GetProcAddress的(HMODULETestFunction);
_assert(pFunc1!= NULL);
TestFunctionPtr PTEST =(TestFunctionPtr)pFunc1;

PVOID pFunc2 = :: GetProcAddress的(HMODULECreateMyObject);
_assert(pFunc2!= NULL);
CreateObjectPtr pCreateObjectFunc =(CreateObjectPtr)pFunc2;

(* PTEST)(); //这个成功弹出一个消息框
(* pCreateObjectFunc)(); //这扔一个EEFileLoadException

返回0;
}

有关它的价值,事件日志报告如下:
.NET运行库版本2.0.50727.143 -
致命的执行引擎错误(79F97075)(80131506)



不幸的是,微软对这个错误没有信息。

解决方案

问题是其中的DLL位置。




  • C:\dlls\managed.dll

  • C:\dlls\wrapper.dll

  • C:\exe \my.exe



我证实了这一点通过复制managed.dll到C:\exe和它的工作没有问题。显然,CLR不会查找托管DLL的非托管DLL的路径,只会寻找它那里的可执行文件。 (或GAC)。



有关理由不值得进入,这是结构我需要的,这意味着我需要给CLR一只手在位于托管的DLL。请参见下面的代码:



AssemblyResolver.h:

  /// <总结> 
///摘要AssemblyResolver
///< /总结>
公共文献类AssemblyResolver
{
公众:

静态大会^ MyResolveEventHandler(对象^发件人,ResolveEventArgs ^参数)
{
控制台:的WriteLine(解决......);

^大会= thisAssembly大会:: GetExecutingAssembly();
^字符串= thisPath&thisAssembly- GT;位置;
^字符串目录=路径:: GetDirectoryName(thisPath);
^字符串= pathToManagedAssembly ::路径组合(目录managed.dll);

^大会= newAssembly大会::的LoadFile(pathToManagedAssembly);
返回newAssembly;
}

};



Wrapper.cpp:

 的#includeAssemblyResolver.h

的externC__declspec(dllexport)的IMyObject * CreateMyObject(无效)
{

{
的AppDomain ^ currentDomain =的AppDomain :: CurrentDomain;
currentDomain-> AssemblyResolve + = gcnew ResolveEventHandler(AssemblyResolver :: MyResolveEventHandler);

返回新CMyWrapper();
}
赶上(系统::例外^ E)
{
系统::控制台:的WriteLine(E->消息);

返回NULL;
}
}


For deployment reasons, I am trying to use IJW to wrap a C# assembly in C++ instead of using a COM Callable Wrapper.

I've done it on other projects, but on this one, I am getting an EEFileLoadException. Any help would be appreciated!

Managed C++ wrapper code (this is in a 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);
}

Test Code (this is an 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;
}

For what it's worth, the Event Log reports the following: .NET Runtime version 2.0.50727.143 - Fatal Execution Engine Error (79F97075) (80131506)

Unfortunately, Microsoft has no information on that error.

解决方案

The problem was where the DLLs were located.

  • c:\dlls\managed.dll
  • c:\dlls\wrapper.dll
  • c:\exe\my.exe

I confirmed this by copying managed.dll into c:\exe and it worked without issue. Apparently, the CLR won't look for managed DLLs in the path of the unmanaged DLL and will only look for it where the executable is. (or in the GAC).

For reasons not worth going into, this is the structure I need, which meant that I needed to give the CLR a hand in located the managed dll. See code below:

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;
    }
}

这篇关于用C使用C#类时EEFileLoadException ++(Win32的应用程序)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆