2015-10-16 9 views
7

ich eine C# DLL (MyTestDll) mit dem NuGet Paket UnmanagedExports gebaut haben:Laden C# DLL mit nicht verwalteten Exporte in Python

[DllExport("Test", CallingConvention = CallingConvention.Cdecl)] 
public static string Test(string name) 
{ 
    return "hi " + name + "!"; 
} 

ich es von Python über ctypes DLL-Import verwenden:

path = "C:\\Temp\\Test" 
os.chdir(path) 
dll = ctypes.WinDLL("MyTestDll.dll") 
f = dll.Test 
f.restype = ctypes.c_char_p 
print f('qqq') 

Es ist nur eine Fantasie, es funktioniert.

Dann habe ich noch eine DLL (NoSenseDll):

namespace NoSenseDll 
{ 
    public class NoSenseClass 
    { 
     public static int Sum(int a, int b) 
     { 
      return a + b; 
     } 
    } 
} 

Ich begann dieses NoSenseDll zu verwenden MyTestDll zu implementieren:

[DllExport("Test", CallingConvention = CallingConvention.Cdecl)] 
public static string Test(string name) 
{ 
    return NoSenseDll.NoSenseClass.Sum(4, 5).ToString(); 
} 

Leider ist es nicht funktioniert. Python sagt:

WindowsError: [Error -532462766] Windows Error 0xE043435 

Ich habe versucht C:\\Temp\\Test auf Pfad hinzufügen, aber das half nicht.


Ich habe einen C++ Test geschrieben:

#include "stdafx.h" 
#include "windows.h" 
#include <iostream> 
#include <string> 
#include "WinBase.h" 

typedef char*(__stdcall *f_funci)(const char*); 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int t; 
    std::string s = "C:\\Temp\\Test\\MyTestDll.dll"; 
    HINSTANCE hGetProcIDDLL = LoadLibrary(std::wstring(s.begin(), s.end()).c_str()); 

    f_funci funci = (f_funci)GetProcAddress(hGetProcIDDLL, "Test"); 

    std::cout << "funci() returned " << funci(std::string("qqq").c_str()) << std::endl; 
    std::cin >> t; 
    return EXIT_SUCCESS; 
} 

Es funktioniert, wenn die zweite DLL (NoSenseDll) im selben Ordner wie die ausführbaren C++ ist. Es funktioniert nicht, wenn ich nur NoSenseDll-Ordner zu PATH hinzufügen.

+0

* Ich habe versucht, 'C: \\ Temp \\ Test' zu Pfad hinzuzufügen, aber das hat nicht geholfen. * Haben Sie wirklich die doppelten Backslashes verwendet? Vielleicht könnte das das Problem sein. Einfach raten. – Palec

+0

Ich habe mein Bestes getan, um Ihre Q & A zu bearbeiten, um leichter verständlich zu sein, und ich reparierte die NoSen * c * eDll zu NoSen * s * eDll. Danke für die Mühe, die du in dieses Q & A gesteckt hast! – Palec

Antwort

4

Draft Lösung:

  1. Kopieren NoSenseDll in den Ordner von Python, in meinem Fall %HOMEPATH%\Anaconda.
  2. Starten Sie IPython/Spyder neu.

Endlösung:

static MyTestDllClass() // static constructor 
{ 
    AppDomain currentDomain = AppDomain.CurrentDomain; 
    currentDomain.AssemblyResolve += new ResolveEventHandler(LoadFromSameFolder); 
} 
static Assembly LoadFromSameFolder(object sender, ResolveEventArgs args) 
{ 
    string folderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
    string assemblyPath = Path.Combine(folderPath, new AssemblyName(args.Name).Name + ".dll"); 
    if (File.Exists(assemblyPath) == false) return null; 
    Assembly assembly = Assembly.LoadFrom(assemblyPath); 
    return assembly; 
} 

Abschließender Hinweis:

Wenn Sie nicht Ironpython wegen matplotlib oder Pandas verwenden können,
wenn Sie nicht verwenden können python.net wegen IPython oder Spyder,
wenn Sie nicht wollen, COM Interop nur weil,
und Sie real Möchten Sie, dass C# und Python zusammen funktionieren, verwenden Sie die obige Lösung und die C# -Reflexion.

+0

können Sie bitte auf Probleme von Python in ipython oder Spyder zeigen? – denfromufa

2

Sie können sich auch Costura.Fody ansehen.

Dies ist eine Build-Task, die Ihre Abhängigkeiten als Ressourcen zu Ihrer Assembly hinzufügt und sogar einen Modulinitialisierer verbindet, um sie zur Laufzeit zu laden.

+0

können Sie ein Beispiel für diesen Fall angeben? Wie anders ist das von deinen unmanaged Exporten? – denfromufa

+1

Sie würden immer noch mein Paket verwenden, aber mit Costura werden Ihre Abhängigkeiten als Ressourcen in Ihre Assembly eingefügt. Costura fügt Haken hinzu, um sie von dort zu laden. –

Verwandte Themen