खोज…


वाक्य - विन्यास

  • [DllImport ("Example.dll")] स्थिर बाहरी शून्य सेटटैक्स (स्ट्रिंग इनस्ट्रिंग);
  • [DllImport ("Example.dll")] स्थिर बाहरी शून्य GetText (StringBuilder outString);
  • [मार्शल (अनमैन्डेडटाइप.बायवेल्स्ट्रेट, साइज़कॉन्स्ट = 32)] स्ट्रिंग टेक्स्ट;
  • [मार्शल (अप्रबंधित टाइप। ByValArray, SizeConst = 128)] बाइट [] byteArr;
  • [StructLayout (LayoutKind.Sequential)] सार्वजनिक संरचना PERSON {...}
  • [StructLayout (LayoutKind.Explicit)] सार्वजनिक संरचना MarshaledUnion {[FieldOffset (0)] ...}

Win32 dll फ़ंक्शन को कॉल करना

using System.Runtime.InteropServices;

class PInvokeExample
{
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern uint MessageBox(IntPtr hWnd, String text, String caption, int options);

    public static void test()
    {
        MessageBox(IntPtr.Zero, "Hello!", "Message", 0);
    }
}

एक फ़ंक्शन को static extern बाहरी स्टिंग के रूप में घोषित करें। DllImportAttribute को इसके Value साथ .dll नाम पर सेट करें। System.Runtime.InteropServices नाम स्थान का उपयोग करना न भूलें। फिर इसे एक नियमित स्थैतिक विधि के रूप में कहें।

प्लेटफ़ॉर्म इनवोकेशन सर्विसेज .dll को लोड करने और वांछित वित्त खोजने का ध्यान रखेगी। सबसे सरल मामलों में पी / इनवॉइस मार्शाल पैरामीटर भी होगा और .dll (यानी .NET डेटाटाइप्स से Win32 वाले और इसके विपरीत में कन्वर्ट) के लिए मान लौटाएगा।

विंडोज एपीआई का उपयोग करना

Pinvoke.net का प्रयोग करें।

अपने कोड में एक extern विंडोज एपीआई फ़ंक्शन की घोषणा करने से पहले, pinvoke.net पर इसकी तलाश करें। वे सबसे अधिक संभावना पहले से ही सभी सहायक प्रकार और अच्छे उदाहरणों के साथ एक उपयुक्त घोषणा है।

मार्शलिंग सरण

सरल प्रकार की सरणियाँ

[DllImport("Example.dll")]
static extern void SetArray(
    [MarshalAs(UnmanagedType.LPArray, SizeConst = 128)]
    byte[] data);

स्ट्रिंग की किरणें

[DllImport("Example.dll")]
static extern void SetStrArray(string[] textLines);

Marshaling संरचनाएं

सरल संरचना

C ++ हस्ताक्षर:

typedef struct _PERSON
{
    int age;
    char name[32];
} PERSON, *LP_PERSON;

void GetSpouse(PERSON person, LP_PERSON spouse);

सी # परिभाषा

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct PERSON
{
    public int age;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string name;
}

[DllImport("family.dll", CharSet = CharSet.Auto)]
public static extern bool GetSpouse(PERSON person, ref PERSON spouse);

अज्ञात आकार सरणी फ़ील्ड के साथ संरचना। में पास हो रहा है

C ++ हस्ताक्षर

typedef struct
{
    int length;
    int *data;
} VECTOR;

void SetVector(VECTOR &vector);

जब प्रबंधित से अप्रबंधित कोड में पारित किया, यह

data ऐरे को इंटप्रेट के रूप में परिभाषित किया जाना चाहिए और मेमोरी को Marshal.AllocHGlobal() साथ स्पष्ट रूप से आवंटित किया जाना चाहिए। Marshal.AllocHGlobal() (और Marshal.FreeHGlobal() afterwords के साथ मुक्त किया गया):

[StructLayout(LayoutKind.Sequential)]
public struct VECTOR : IDisposable
{
    int length;
    IntPtr dataBuf;

    public int[] data
    {
        set
        {
            FreeDataBuf();
            if (value != null && value.Length > 0)
            {
                dataBuf = Marshal.AllocHGlobal(value.Length * Marshal.SizeOf(value[0]));
                Marshal.Copy(value, 0, dataBuf, value.Length);
                length = value.Length;
            }
        }
    }
    void FreeDataBuf()
    {
        if (dataBuf != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(dataBuf);
            dataBuf = IntPtr.Zero;
        }
    }
    public void Dispose()
    {
        FreeDataBuf();
    }
}

[DllImport("vectors.dll")]
public static extern void SetVector([In]ref VECTOR vector);

अज्ञात आकार सरणी फ़ील्ड के साथ संरचना। प्राप्त करना

C ++ हस्ताक्षर:

typedef struct
{
    char *name;
} USER;

bool GetCurrentUser(USER *user);

जब इस तरह के डेटा को IntPrt कोड से पास किया जाता है और मेमोरी को IntPrt फ़ंक्शंस द्वारा आवंटित किया जाता है, तो प्रबंधित कॉलर को इसे IntPrt चर में प्राप्त करना चाहिए और बफर को एक प्रबंधित सरणी में बदलना चाहिए। तार के मामले में एक सुविधाजनक Marshal.PtrToStringAnsi() विधि:

[StructLayout(LayoutKind.Sequential)]
public struct USER
{
    IntPtr nameBuffer;
    public string name { get { return Marshal.PtrToStringAnsi(nameBuffer); } }
}

[DllImport("users.dll")]
public static extern bool GetCurrentUser(out USER user);

यूनियनों को चिन्हित करना

केवल मूल्य-प्रकार फ़ील्ड्स

सी ++ घोषणा

typedef union
{
    char c;
    int i;
} CharOrInt;

सी # घोषणा

[StructLayout(LayoutKind.Explicit)]
public struct CharOrInt
{
    [FieldOffset(0)]
    public byte c;
    [FieldOffset(0)]
    public int i;
}

मूल्य-प्रकार और संदर्भ क्षेत्रों का मिश्रण

एक मूल्य प्रकार के साथ एक संदर्भ मूल्य को ओवरलैप करने की अनुमति नहीं है, इसलिए आप बस का उपयोग नहीं कर सकते FieldOffset(0) text; FieldOffset(0) i; के लिए संकलन नहीं करेगा

typedef union
{
    char text[128];
    int i;
} TextOrInt;

और आम तौर पर आपको कस्टम मार्शलिंग को नियोजित करना होगा। हालाँकि, विशेष मामलों में इस तरह की सरल टेकनीक का उपयोग किया जा सकता है:

[StructLayout(LayoutKind.Sequential)]
public struct TextOrInt
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
    public byte[] text;
    public int i { get { return BitConverter.ToInt32(text, 0); } }
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow