2015-02-12 4 views
6

कल्पना कीजिए मैं एक समारोहPInvoke

Myfunction(const void * x); 

मेरे सी # घोषणा कहा जाता है हो सकता है

MyFunction(IntPtr x); 

इस कार्यात्मक और तकनीकी रूप से

struct MyStruct { IntPtr P; } 

MyFunction(MyStruct x); 
के बराबर है

या इसमें कोई अंतर होगा कि वे कैसे मार्शल किए गए हैं।

मैं यह पूछ रहा हूं क्योंकि जिस लाइब्रेरी को मैं कॉल कर रहा हूं वह सभी शून्य है, अन्य नामों के लिए टाइप किया गया है, और सी # में मैं टाइप सुरक्षा चाहता हूं, इसके लायक होने के लिए।

+1

यह प्रश्न नीचे उबलता है: क्या एक सदस्य के साथ एक संरचना उस सदस्य के प्रकार के समान ही मार्शल हो गई है? जबकि मुझे नहीं पता, मैं * दृढ़ता से * संदेह नहीं करता। – BradleyDotNET

+0

कोई सीधा जवाब नहीं है, लेकिन अतीत में मैंने हमेशा एक नई संरचना बनाई है जो इंटप्राट को लपेटती है (जैसे आप प्रस्तावित कर रहे हैं) जिसे "जो भी पीटीआर" कहा जाता है, जहां "जो भी" मेरा अप्रबंधित प्रकार है, और उसके बाद एक कस्टम मार्शलर का उपयोग कर ICustomMarshaller इंटरफ़ेस https://msdn.microsoft.com/en-us/library/d3cxf9f0(v=vs.90).aspx फिर आप स्क्रू नहीं कर सकते और अपने IntPtrs को मिश्रित नहीं कर सकते हैं। यह भी अधिक स्वयं दस्तावेज है, हालांकि आपको बॉयलरप्लेट कोड का थोड़ा सा मंथन करना होगा। ऐसा लगता है कि मार्शलर जादुई रूप से थूक जाएगा या आपकी संरचना –

उत्तर

3

यदि आपका स्ट्रक्चरआउट अनुक्रमिक है, तो यह वास्तव में समान है।

public struct Foo 
    { 
     public IntPtr x; 
    } 

    [DllImport(@"Win32Project1.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl)] 
    public static extern void MyFunctionWithIntPtr(IntPtr x); 

    [DllImport(@"Win32Project1.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl)] 
    public static extern void MyFunctionWithStruct(Foo x); 

    static void Main(string[] args) 
    { 
     IntPtr j = new IntPtr(10); 
     var s = new Foo(); 
     s.x = new IntPtr(10); 
     MyFunctionWithIntPtr(j); 
     MyFunctionWithStruct(s); 
    } 

:

extern "C" 
{ 
    __declspec(dllexport) void MyFunction(const void* ptr) 
    { 
     // put a breakpoint and inspect 
    } 
} 

एक सी # परियोजना बनाओ:

एक सी ++ Win32 DLL परियोजना बनाओ:

खुद के लिए यह सत्यापित करने के लिए

सबसे आसान तरीका है, इसे आज़माने के लिए निश्चित रूप से है अपनी डीबग सेटिंग्स में, सुनिश्चित करें कि आप मूल डिबगिंग सक्षम हैं चुनें।

आप दोनों मान 0xA होने के लिए देखेंगे।

नोट, हालांकि, यदि आप अपने IntPtr बनाम स्ट्रक्चर के लिए आउट/रेफ पैरामीटर का उपयोग करते हैं, तो वे अलग-अलग मान होंगे।

+0

परीक्षण और त्रुटि कुछ भी साबित नहीं करेगा। आप कैसे जानते हैं कि एक और उदाहरण अलग-अलग व्यवहार नहीं करता है? –

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