2010-05-12 3 views
6

मैं PInvoke और DllImport विशेषता का उपयोग कर बाहरी अप्रबंधित डीएल का उपयोग कर रहा हूं। जैसे।सेट DllImport विशेषता गतिशील रूप से

[DllImport("mcs_apiD.dll", CharSet = CharSet.Auto)] 
private static extern byte start_api(byte pid, byte stat, byte dbg, byte ka); 

मैं अगर यह dynmically कुछ तरीके से dll फ़ाइल विवरण (इस उदाहरण में mcs_apiD.dll) को बदलने के लिए संभव है सोच रहा हूँ, अगर उदाहरण के लिए मैं एक dll संस्करण के खिलाफ निर्माण करना चाहता था

उत्तर

2

आप कर सकते हैं डीएलएल का नाम बदल नहीं है लेकिन आप लाइब्रेरी लोड होने के पथ को बदल सकते हैं (जैसे इसे रजिस्ट्री या कॉन्फ़िगरेशन फ़ाइल से पढ़कर) और LoadLibrary कर्नेल 32 के फ़ंक्शन के साथ इसे मैन्युअल रूप से लोड करें: see my answer there

+0

ठीक है। लेकिन मेरे उदाहरण में मैंने एक विशिष्ट फ़ंक्शन प्रोटोटाइप निर्दिष्ट किया है ताकि मैं पैरामीटर को सही ढंग से मर्सल कर सकूं, कुछ एपीआई फ़ंक्शंस में पैरामीटर के रूप में जटिल संरचनाएं होती हैं। इस तरह से काम करते समय मैं यह कैसे करूँगा? – user226356

+0

यदि पैरामीटर डीएलएल के एक संस्करण से दूसरे में बदलते हैं, तो आप –

5

हां यह संभव है, आपको उस नौकरी का हिस्सा करना होगा जो पी/Invoc marshaller करता है। डीएलएल लोड हो रहा है और निर्यात किए गए फ़ंक्शन के प्रवेश बिंदु को ढूंढ रहा है। एक प्रतिनिधि जिनके हस्ताक्षर निर्यात समारोह से मेल खाता है की घोषणा के द्वारा शुरू करें:

private delegate byte start_api(byte pid, byte stat, byte dbg, byte ka); 

तो इस तरह कोड का उपयोग करें:

using System.ComponentModel; 
using System.Runtime.InteropServices; 
    ... 

    static IntPtr dllHandle; 
    ... 
     if (dllHandle == IntPtr.Zero) { 
      dllHandle = LoadLibrary("mcs_apiD.dll"); 
      if (dllHandle == IntPtr.Zero) throw new Win32Exception(); 
     } 
     IntPtr addr = GetProcAddress(dllHandle, "[email protected]"); 
     if (addr == IntPtr.Zero) throw new Win32Exception(); 
     var func = (start_api)Marshal.GetDelegateForFunctionPointer(addr, typeof(start_api)); 
     var retval = func(1, 2, 3, 4); 
    ... 
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr LoadLibrary(string name); 
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] 
    private static extern IntPtr GetProcAddress(IntPtr hModule, string name); 

तरीके निश्चित रूप से यह गलत पाने के लिए बहुत सारे। ध्यान दें कि आपको डीएलएल से वास्तविक निर्यात किए गए नाम का उपयोग करना है, अब आपको नाम सजावट में सहायता के लिए पी/इनवॉक मार्शलर से सहायता नहीं मिलती है। यदि आप सुनिश्चित नहीं हैं कि निर्यात नाम कैसा दिखता है तो DLL पर dumpbin.exe/निर्यात का उपयोग करें।

+0

का उल्लेख करते हुए विधि के साथ भाग्य से बाहर हैं, वास्तव में डीएलएल एपीआई के प्रति प्रतिनिधि 1 संस्करण के साथ GetProcAddress के साथ संयुक्त, आप अपना रास्ता निकाल लेंगे यह –

+0

इस पर एक माइक्रोसॉफ्ट ब्लॉग आलेख है: http://blogs.msdn.com/b/jonathanswift/archive/2006/10/03/dynamically-calling-an-unmanaged-dll-from-.net-_2800_c_23002900_ .aspx – Deanna

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

  • कोई संबंधित समस्या नहीं^_^