2010-03-12 14 views
11

पर .NET P/Invoke कोड को व्यवस्थित करने के लिए सर्वोत्तम अभ्यास। मैं .NET में एक बड़े और जटिल कोड बेस का पुन: उपयोग कर रहा हूं जो Win32 APIs में P/Invoke का भारी उपयोग करता है। परियोजना की संरचना सबसे बड़ी नहीं है और मैं DllImport बयान लग रहा है हर जगह, बहुत बार एक ही समारोह के लिए दोहराया गया, और भी तरीके की एक किस्म में की घोषणा की:Win32 एपीआई

आयात निर्देशों और तरीकों कभी कभी के रूप में घोषित किया गया है सार्वजनिक, कभी-कभी निजी, कभी-कभी स्थैतिक और कभी-कभी उदाहरण विधियों के रूप में। मेरी चिंता यह है कि रिफैक्टरिंग में अनपेक्षित परिणाम हो सकते हैं लेकिन यह अपरिहार्य हो सकता है।

क्या वहां सर्वोत्तम प्रथाओं का दस्तावेज है जो मैं अनुसरण कर सकता हूं जो मेरी मदद कर सकता है?

मेरे instict एक स्थिर/साझा Win32 पी/आह्वान एपीआई वर्ग कि एक फ़ाइल में इन तरीकों और संबंधित स्थिरांक की सभी सूचीबद्ध करता है ... संपादित व्यवस्थित करने के लिए user32 DLL करने के लिए 70 से अधिक आयात कर रहे हैं है।

(कोड बेस खिड़कियों संदेश गुजर और पार धागा कॉल का एक बहुत साथ 20 से अधिक परियोजनाओं से बना है। यह भी एक VB.NET परियोजना VB6 से उन्नत किया है कि यदि एक फर्क नहीं पड़ता।)

उत्तर

5

आप .NET ढांचे में किए गए तरीके पर विचार कर सकते हैं। यह अनिवार्य रूप से एक स्थिर वर्ग (वीबीएनईटी में मॉड्यूल) घोषित करता है जिसका नाम नेटिव मोड्स है जिसमें पी/आमंत्रण घोषणाएं शामिल हैं। आप माइक्रोसॉफ्ट प्रोग्रामर की तुलना में अधिक व्यवस्थित हो सकते हैं, कई डुप्लिकेट घोषणाएं हैं। ढांचे के विभिन्न हिस्सों पर काम कर रहे विभिन्न दल।

हालांकि, अगर आप इसे सभी परियोजनाओं में साझा करना चाहते हैं तो आपको इन घोषणाओं को घोषित करना होगा मित्र के बजाय सार्वजनिक। जो महान नहीं है, यह एक कार्यान्वयन विस्तार होना चाहिए। मुझे लगता है कि आप इसे हर परियोजना में स्रोत कोड फ़ाइल का पुन: उपयोग करके हल कर सकते हैं। आम तौर पर वर्जित लेकिन इस मामले में ठीक है, मुझे लगता है।

मैं उन्हें व्यक्तिगत रूप से उन स्रोत कोड फ़ाइल में आवश्यक घोषित करता हूं जिन्हें उन्हें निजी बनाने की आवश्यकता होती है। यह तर्क प्रकारों के बारे में झूठ बोलने में भी वास्तव में मदद करता है, खासकर SendMessage के लिए।

+0

महान चर्चा के लिए सभी को धन्यवाद। बहुत बुरा मैं कर सकता हूँ। केवल एक विजेता चुनें। बहुत व्यावहारिक विचारों के लिए धन्यवाद nobugz। –

2

क्या मैं आम तौर पर इस मामले में ऐसा करने की कोशिश करता हूं जो आप बात कर रहे हैं, विभिन्न वर्गों, स्थैतिक या नहीं, जो कार्यक्षमता प्रदान करते हैं, इस तरह इसे आवश्यकतानुसार पुनः उपयोग किया जा सकता है। कॉल की प्रकृति के आधार पर, मैं एक स्थिर वर्ग कार्यान्वयन से शर्मनाक तरीका चाहता हूं, लेकिन यह आपके विशिष्ट कार्यान्वयन पर निर्भर करेगा।

अनुरोध के अनुसार ऊपर विस्तार।

पी/Invoke की प्रकृति को देखते हुए, विशेष रूप से यदि कई कॉल की आवश्यकता है और कार्यान्वयन के विभिन्न क्षेत्रों के हैं, तो मुझे वस्तुओं की तरह समूह के साथ बेहतर होना बेहतर लगता है, इस तरह आप कई अन्य अव्यवस्था में नहीं खींच रहे हैं, या जब आवश्यक नहीं हो तो अन्य डीएलएल आयात।

इच्छा स्थिर तरीकों से दूर रहने की, .. अप्रबंधित संसाधनों और मेमोरी लीक आदि के लिए क्षमता के लिए कॉल की वजह से है

+0

मिशेल, क्या आप अपने उत्तर पर विस्तार करना चाहते हैं? आप एक के बजाय विभिन्न कक्षाएं क्यों बनायेंगे? और स्थिर कार्यान्वयन कम बेहतर क्यों होगा? –

+0

प्रति अनुरोध अपडेट किया गया –

2

क्यों एक विलक्षण Win32.vb बुलाया फ़ाइल नहीं बना सकते हैं और है कि तार्किक समूह के भीतर में pinvokes उदाहरण के लिए अलग-अलग नामस्थान, एक जीडीआई नेमस्पेस सभी जीडीआई पिनवोक्स का उपयोग कर सकता है, उपयोगकर्ता 32 नामस्थान उपयोगकर्ता 32 कर्नेल में मौजूद सभी पिनवोक्स का उपयोग कर सकता है, और इसी तरह .... यह पहले दर्दनाक हो सकता है, लेकिन कम से कम आपके पास केंद्रीकृत नामस्थान होंगे सब उस फाइल के भीतर निहित है? मेरा मतलब क्या है इसका मतलब देखने के लिए here देखें ... आपको क्या लगता है?

+0

+1 ग्रेट लिंक! निश्चित रूप से उस चीज़ का एक महान उदाहरण जो मैं करना चाहता हूं। –

+0

लिंक तोड़ दिया। –

2

क्या आपका पी/Invoke VB6 से माइग्रेशन का आर्टिफैक्ट कॉल करता है? मैंने VB6 से C# (Windows.Forms और System.EnterpriseServices) से कोड की 300,000 लाइनों को माइग्रेट कर दिया है, और कुछ हद तक पी/इनवॉक्स कॉल को हटा दिया है - लगभग हमेशा एक प्रबंधित समतुल्य है। यदि आप रिफैक्टरिंग कर रहे हैं, तो आप कुछ ऐसा करने पर विचार करना चाहेंगे। परिणामी कोड बनाए रखने के लिए उचित आसान होना चाहिए।

+0

लंबे समय तक बनाए रखने के लिए न केवल आसान है, बल्कि अधिक प्रदर्शन करने वाला भी है। – Nick

+0

कुछ कॉल कलाकृतियों हैं और कुछ नहीं हैं। मैं वास्तव में w/प्रबंधित कोड को बदल रहा हूं लेकिन पी/आवेक की एक महत्वपूर्ण राशि बनी रहेगी। –

+3

वह perf की मदद नहीं करता है, प्रबंधित विधि अभी भी P/Invokes। –

2

अनुशंसित तरीका आंतरिक दृश्यता के साथ सभी डीएल आयातित विधियों के साथ प्रति असेंबली क्लास प्रति असेंबली होना है। इस तरह से आप हमेशा जानते हैं कि आपका आयातित कार्य कहां है और डुप्लिकेट घोषणाओं से बचें।

+0

दिलचस्प लगता है। क्या आप कुछ स्रोतों के लिए एक लिंक या दो प्रदान कर सकते हैं। –

+0

FxCop ऐसा करने का सुझाव देता है .. http://blogs.msdn.com/fxcop/archive/2007/01/14/faq-how-do-i-fix-a-violation-of-movepinvokestonativemethodsclass पर एक नज़र डालें। एएसपीएक्स – munissor

2

उन्हें [Safe|Unsafe]NativeMethods class में व्यवस्थित करें। कक्षा को internal static के रूप में चिह्नित करें। यदि आपको उन्हें अपनी असेंबली में बेनकाब करने की आवश्यकता है, तो आप InternalsVisibleTo का उपयोग कर सकते हैं - हालांकि यदि आप प्रत्येक असेंबली में संबंधित समूह को समूहित कर सकते हैं तो यह अधिक उपयुक्त होगा।

प्रत्येक विधि static होना चाहिए - मुझे ईमानदारी से पता नहीं था कि आप DllImport के साथ उदाहरण विधियों को भी चिह्नित कर सकते हैं।

पहले चरण के रूप में - मैं शायद सबकुछ कोर असेंबली (यदि आपके पास है) में ले जायेगा, या Product.Native असेंबली बनाएं। फिर आप आसानी से डुप्लिकेट और ओवरलैप पा सकते हैं, और प्रबंधित समकक्षों की तलाश कर सकते हैं। यदि आपके पी/आवेषण एक गड़बड़ हैं, तो मुझे संदेह नहीं है कि आपके पास अन्य असेंबली में लेयरिंग के तरीके में बहुत कुछ है जो आपके समूह को मार्गदर्शन करेगा।