2015-10-16 29 views
7

मैं एक सी # DLL (MyTestDll) का निर्माण किया है NuGet पैकेज UnmanagedExports का उपयोग कर:लोड हो रहा है सी # DLL

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

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

मैं ctypes DLL आयात के माध्यम से अजगर से इसका इस्तेमाल करते हैं

यह सिर्फ एक कल्पना है, यह काम करता है।

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

मैं MyTestDll लागू करने के लिए इस NoSenseDll उपयोग शुरू कर दिया:

फिर, मैं एक और DLL (NoSenseDll) जोड़ा

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

दुर्भाग्य से, यह काम नहीं करता। अजगर का कहना है:

WindowsError: [Error -532462766] Windows Error 0xE043435 

मैं रास्ते पर C:\\Temp\\Test जोड़ने की कोशिश की है, लेकिन है कि मदद नहीं की।


मैं एक सी ++ परीक्षण लिखा है:

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

यह काम करता है, तो दूसरा DLL (NoSenseDll) सी ++ निष्पादन को उसी फ़ोल्डर में है। यह काम नहीं करता है अगर मैं सिर्फ पैथ में NoSenseDll फ़ोल्डर जोड़ता हूं।

+0

* मैंने पथ में 'सी: \\ टेम्प \\ टेस्ट' जोड़ने की कोशिश की है, लेकिन इससे मदद नहीं मिली। * क्या आपने वास्तव में डबल बैकस्लैश का उपयोग किया था? शायद यह समस्या हो सकती है। सिर्फ अनुमान। – Palec

+0

मैंने आपके क्यू एंड ए को अधिक आसानी से समझने के लिए संपादित करने के लिए अपनी पूरी कोशिश की, और मैंने नोसेन * सी * ईडीएल को नोसेन * एस * ईडीएल में तय किया। इस क्यू एंड ए में किए गए प्रयासों के लिए धन्यवाद! – Palec

उत्तर

4

ड्राफ्ट समाधान:

  1. कॉपी NoSenseDll अजगर के फ़ोल्डर में, मेरे मामले %HOMEPATH%\Anaconda में।
  2. आईपीथॉन/स्पाइडर को पुनरारंभ करें।

अंतिम समाधान:

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

अंतिम नोट:

आप matplotlib या पांडा की वजह से IronPython का उपयोग नहीं कर सकते हैं,
यदि आप उपयोग नहीं कर सकते python.net आईपीथन या स्पाइडर की वजह से,
यदि आप COM इंटरऑप का उपयोग नहीं करना चाहते हैं, तो
और आप असली ly एक साथ काम करने के लिए सी # और पायथन प्राप्त करना चाहते हैं, उपरोक्त समाधान और सी # प्रतिबिंब का उपयोग करें।

+0

क्या आप कृपया ipython या spyder में पायथननेट से मुद्दों को इंगित कर सकते हैं? – denfromufa

2

आप Costura.Fody भी देख सकते हैं।

यह एक ऐसा कार्य कार्य है जो आपकी निर्भरताओं को आपकी असेंबली में संसाधनों के रूप में जोड़ देगा और यहां तक ​​कि रनटाइम पर लोड करने के लिए मॉड्यूल प्रारंभकर्ता को भी हुक करेगा।

+0

क्या आप इस मामले के लिए उदाहरण प्रदान कर सकते हैं? यह आपके अप्रबंधित निर्यात से कितना अलग है? – denfromufa

+1

आप अभी भी मेरे पैकेज का उपयोग करेंगे, लेकिन कोस्टुरा के साथ, आपकी निर्भरताओं को आपकी असेंबली में संसाधनों के रूप में जोड़ा जाएगा। कोस्टुरा हुक को वहां से लोड करने के लिए जोड़ता है। –

2

आप सीधे प्रबंधित कोड के साथ ऐसा नहीं कर सकते हैं। आप से रजिस्टर COM वस्तु dll:

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\regasm.exe my.dll /tlb:my.tlb /codebase 

और अजगर से कॉम फोन करना। यहां देखें उदाहरण: http://www.codeproject.com/Articles/73880/Using-COM-Objects-in-Scripting-Languages-Part-Py

संबंधित मुद्दे