2010-01-19 8 views
6

एक मूल एपीआई को PInvoke दोस्ताना कैसे बनाया जाए?एक PInvoke दोस्ताना देशी-एपीआई कैसे बनाया जाए?

पी/Invoke here के साथ उपयोग किए जाने वाले देशी कार्यक्रमों को संशोधित करने के तरीके पर कुछ सुझाव दिए गए हैं। लेकिन इससे पहले कि मैं एक देशी कार्यक्रम भी लिखूं, मेरे कार्यक्रम/पुस्तकालय PInvoke दोस्ताना बनाने के लिए मुझे क्या चीजें देखना चाहिए?

सी या सी ++ का उपयोग कर ठीक है।


अद्यतन:

[DLLimport("MyDLL.dll")] 

यह करने के लिए संभव है:
अगर मैं एक सी एपीआई लिखते हैं, क्या बातें मैं ऐसा करने के लिए वह यह है कि यह पी/आह्वान करने योग्य निम्नलिखित की तरह सी # सिंटैक्स का उपयोग कर रहे हैं मूल सी ++ कोड/पुस्तकालय के साथ ही?


सारांश/अलग तरीके से व्यक्त कुछ टिप्स की एक पी बनाने के लिए/आह्वान अनुकूल देशी-एपीआई:
+ पैरामीटर देशी प्रकार का होना चाहिए (int, चार *, नाव, ...)
+ कम मापदंडों बेहतर
है + यदि गतिशील मेमोरी आवंटित की जाती है और प्रबंधित कोड पर पास की जाती है, तो सुनिश्चित करें कि "क्लीनर" फ़ंक्शन बनाना सुनिश्चित करें जो 0/ + नमूने और/या यूनिट परीक्षण प्रदान करता है जो बताता है कि एपीआई को .NET
से कैसे कॉल करें + सी ++/सीएलआई रैपर प्रदान करें

उत्तर

1

परिभाषा के अनुसार प्रत्येक मूल कार्य को प्रबंधित कोड से पी/बुलाया जा सकता है। लेकिन पी/दोस्ताना दोस्ताना होने के लिए एक समारोह में जितना संभव हो उतना पैरामीटर होना चाहिए जो मूल प्रकार (int, char *, float, ...) होना चाहिए। इसके अलावा यदि कोई फ़ंक्शन कुछ पॉइंटर पर स्मृति आवंटित करता है जो प्रबंधित कोड पर वापस लौटाया जाता है, तो सुनिश्चित करें कि आप अपना काउंटर हिस्सा लिखेंगे जो पॉइंटर को मुक्त करेगा क्योंकि प्रबंधित कोड अप्रबंधित कोड से आवंटित स्मृति को मुक्त नहीं कर सकता है।

+0

"एक समारोह जो देशी प्रकार (int, चार *, नाव, ...) का होना चाहिए संभव के रूप में कुछ पैरामीटर होने चाहिए" मैं इस पर संक्षेप में प्रस्तुत कर सकते हैं: -> मापदंडों देशी प्रकार की होनी चाहिए (int, char *, float, ...) -> कम पैरामीटर बेहतर है -> यदि गतिशील मेमोरी आवंटित की जाती है और प्रबंधित कोड में पास की जाती है, तो सुनिश्चित करें कि "क्लीनर" फ़ंक्शन बनाना है जो पी/आक्रमण –

+0

हां , यह एक अच्छा सारांश है। –

1

सही ढंग से सी # या .NET से बुला का एक उदाहरण प्रदान करें, और भी बेहतर एक .NET वर्ग है कि अपने सभी तरीकों

कि आपके कोड साबित होता है nunit के साथ एक सरल इकाई परीक्षण लेखन ठीक से काम करता लपेटता प्रदान जब .Net से बुलाया जाता है तो यह करने के लिए तरीका होगा।

भी याद रखें कि नेट डेवलपर्स है कि आपके कोड बुला होने की संभावना है सी के बारे में पता करने के लिए ++ संभावना नहीं है, या विभिन्न डेटा प्रकार आदि के आकार पता नहीं है या कैसे इन प्रकार PInvoke विशेषताओं को मैप ।

सभी के बारे में सोचें कि आप अपने क्लाइंट कोड को कैसे देखना चाहते हैं और उसके बाद एक एपीआई डिज़ाइन करते हैं जो इसे अनुमति देता है।

3

पी/Invoke का उपयोग करने के बजाय, यदि आप मूल पुस्तकालय को स्वयं नियंत्रित कर रहे हैं, तो आप मूल कॉल को लपेटने वाले सी ++/सीएलआई कक्षाओं का एक सेट लिख सकते हैं। कई मामलों में, यह प्लेटफॉर्म आवेषण का उपयोग करने से बेहतर प्रदर्शन करेगा, और आपको प्रकार की शुद्धता का अतिरिक्त लाभ मिलता है।

struct SomeStruct { 
    int a, b; 
    int* somePtr; 
}; 

int foo(struct SomeStruct* a, int b) { 
    *a->somePtr = a->a + a->b; 
    return a->b * *a->somePtr + b; 
} 

आप बना सकते हैं: उदाहरण के लिए, यदि आप निम्नलिखित की तरह सी एपीआई के कुछ प्रकार है (यह कुछ भी उपयोगी नहीं करता है, मैं सिर्फ जोड़ा संकेत और structs तथ्य यह है कि यह मूल कोड है सुदृढ़ करने के लिए) एक C++/CLI वर्ग यह रैप करने के लिए: फिर

public ref class MyNativeAPI { 
    private: 
    SomeStruct* x; 
    public: 
    MyNativeAPI() { 
     x = new SomeStruct; 
    } 
    ~MyNativeAPI() { 
     delete x; 
    } 
    int Foo(int a) { 
     pin_ptr<SomeStruct*> ptr = this->x; 
     return foo(ptr, a); 
    } 
} 

, आप सी # में इस कॉल कर सकते हैं:

MyNativeAPI a = new MyNativeAPI(); 
if(a.Foo(5) > 5) { ... }; 

आप आप नए नियंत्रण को समझने के लिए C++/CLI के बारे में अधिक पढ़ने के लिए होगा दोनों प्रबंधित दोनों पर एपी और देशी ढेर, और दो गुना मिश्रण करने के लिए चेतावनी (जैसे pin_ptr मैंने ऊपर उपयोग किया), लेकिन समग्र रूप से यह .NET में देशी इंटरऑप को पूरा करने के लिए एक और अधिक सुरुचिपूर्ण समाधान है।

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