Frage

Für den Einsatz Gründen Ich versuche IJW zu verwenden, um eine C # Montage in C ++ zu wickeln, anstatt eine COM Callable Wrapper zu verwenden.

Ich habe es auf andere Projekte gemacht, aber auf diesen einen, ich bin immer ein EEFileLoadException. Jede mögliche Hilfe würde geschätzt!

Managed C ++ Wrapper-Code (dies ist in einer 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 (dies ist eine 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;
}

Für das, was es wert ist, meldet das Ereignisprotokoll die folgenden: .NET Runtime Version 2.0.50727.143 - Fatal Execution Engine Error (79F97075) (80.131.506)

Leider hat Microsoft noch keine Informationen zu diesem Fehler.

War es hilfreich?

Lösung

Das Problem war, wo die DLLs wurden entfernt.

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

Ich bestätige dies durch managed.dll in c Kopieren: \ exe und es funktioniert ohne Probleme. Offenbar sucht die CLR nicht für verwaltete DLLs in dem Pfad der nicht verwalteten DLL und wird nur danach suchen, wo die ausführbare Datei ist. (Oder im GAC).

Aus Gründen nicht lohnenswert in, das ist die Struktur ich brauche, was bedeutete, dass ich brauchte, um die CLR eine Hand in sich das verwaltete DLL zu geben. Siehe Code unten:

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

Andere Tipps

Die erste Ausgabe ist der Debugger-Typ, um sicherzustellen, gemischte gesetzt. Dann sind Sie nützliche Ausnahmen erhalten.

Für Sie native Anwendung Verbrauchen des gemischten Modus dll (EXE), die Änderung ** "Debugger Type" auf "Mixed" -Modus. (Zum Projekteigenschaften -> Konfigurationseigenschaften -> Debugging)

Es gibt einige andere Punkte (die Sie möglicherweise nicht relevant sein), aber in meiner Erfahrung konnte sie Probleme verursachen.  - Unter Windows 8 (mit engeren Sicherheits) versuchen Sie, VS als Administrator starten.  - Stellen Sie sicher, dass für x86-Konfiguration Sie x86-Binärdateien verwenden.  -. Achten Sie auf Strong Überprüfung, wenn Ihre C # Baugruppen, die Sie in Managed C ++ als signierte verbrauchen, beachten Sie bitte auch den gemischten Modus dll Unterzeichnung

Hope dies dazu beitragen würde.

Falls jemand stolpert sonst auf diese Frage, und Sie sind eine dynamische Assembly Namen. Sicherstellen, dass Sie den Namen der Assembly sind Strippen kann es Version, Kultur und andere Inhalte, die Sie möglicherweise nicht verwenden

.

D.h., Ihre MyResolveEventHandler in Form sein sollte:

static Assembly^ MyResolveEventHandler( Object^ sender, ResolveEventArgs^ args )
{
    Console::WriteLine( "Resolving..." );

    String^ assemblyName = args->Name;

    // Strip irrelevant information, such as assembly, version etc.
    // Example: "Acme.Foobar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
    if( assemblyName->Contains(",") ) 
    {
        assemblyName = assemblyName->Substring(0, assemblyName->IndexOf(","));
    }

    Assembly^ thisAssembly = Assembly::GetExecutingAssembly();
    String^ thisPath = thisAssembly->Location;
    String^ directory = Path::GetDirectoryName(thisPath);
    String^ pathToManagedAssembly = Path::Combine(directory, assemblyName );

    Assembly^ newAssembly = Assembly::LoadFile(pathToManagedAssembly);
    return newAssembly;
}

Ich war immer die C ++ EEFileLoadException viel von iisexpress.exe beim Debuggen einer ASP.NET MVC-Anwendung geworfen. Der Call-Stack und C ++ Ausnahme selbst war nicht sehr hilfreich bei mir zu helfen, das Problem zu.

direkt an der Zeigeradresse Nach einem Blick in die C ++ Ausnahme gegeben entdeckte ich schließlich eine Bibliothek Zeichenfolge, die auf eine alte Version zeigen war nicht mehr in Gebrauch. Dies wiederum war aufgrund eines out-of-date Eintrag in meiner Datei web.config:

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
    <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
  </dependentAssembly> </assemblyBinding> </runtime>

hatte ich verschiedene Microsoft.Own Sicherheitsbibliotheken über NuGet auf Version 4.0.30319 aktualisiert, aber diese Linie in der Config wurde Anweisen der Server Anrufe auf Version 3.0.1.0 zu umleiten, die jetzt nicht mehr Teil meines Projektes war. Aktualisieren der Konfigurations resovled meine Probleme.

Wenn Sie in Debugger C ++ ausführen nativen Projekt, das mit C ++ dll Sie es geschafft, diese Ausnahme erhalten kann. Wenn VS2010 fangen sie und ihre Bewerbung nach einigen Ketten Ausnahmen abgebrochen werden Sie in Ausnahmefilter versuchen können (Menü | Debug | Excpetion) Deaktivieren Sie alle Ausnahmen ++ C. Sie werden immer noch diese Ausnahme in der Ausgabe sehen, aber Ihre Anwendung wird nicht abbrechen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top