2009-05-08 6 views
13

मैं एक सी एपीआई बना रहा हूं जो एक डीएलएल फ़ाइल में कुछ कार्यक्षमता छुपाता है।सी इंटरफेस में हैंडल के लिए सही प्रकार

चूंकि सब कुछ अंदर सी ++ है, अधिकांश कार्यों में हैंडल के खिलाफ काम करता है जो सीधे एपीआई के अंदर इस पॉइंटर्स को मानचित्र करता है।

उन हैंडल के लिए प्रकार सुरक्षा की कुछ डिग्री प्राप्त करने के लिए मैं उन्हें इस तरह परिभाषित करते हैं:

typedef struct MyType1* MyType1Handle; 
typedef struct MyType2* MyType2Handle; 

मैं वास्तव में किसी भी स्थान पर MyType1 या MyType2 परिभाषित नहीं करते के बाद से मैं सिर्फ उन्हें संकेत के रूप में इस्तेमाल करते हैं और एक कर एपीआई के अंदर वास्तविक सूचक प्रकार के लिए कास्ट टाइप करें।

मेरे समस्या यह है कि जब दृश्य स्टूडियो में एक clr परियोजना में मेरी लाइब्रेरी का उपयोग कर मैं इस warning: unresolved typeref token (token) for 'type'; image may not run.

http://msdn.microsoft.com/en-us/library/h8027ys9(VS.80).aspx

यह कोई बड़ी बात नहीं है, क्योंकि यह काम करता है प्राप्त है, लेकिन यह अव्यवसायिक लग रहा है।

मैं शून्य * का उपयोग कर पसंद नहीं है:

typedef void* MyType1Handle; 
typedef void* MyType2Handle; 

यह यह संभव एक MyType2Handle के साथ एक MyType1Handle चाहते हैं क्योंकि वे वास्तव में एक ही प्रकार के होते हैं एक समारोह कॉल करने के लिए बनाता है।

एक और दृष्टिकोण मैं का उपयोग नहीं करना चाहते हैं तो इस

typedef int MyType1Handle; 
typedef int MyType2Handle; 

की तरह कुछ यह ठीक जब तक पूर्णांक के और संकेत दिए गए एक ही आकार है काम करेंगे, लेकिन यह हमेशा ऐसा नहीं है और यह वहाँ की तरह लगता है प्लेटफ़ॉर्म विशिष्ट पॉइंटर आकार पूर्णांक प्राप्त करने का कोई मूर्ख तरीका नहीं है। यह वही प्रकार की सुरक्षा समस्याएं हैं जो शून्य * के रूप में भी हैं।

एक और दृष्टिकोण मैंने कोशिश की इस तरह यह करने के लिए किया गया था:

struct MyType1{}; 
typedef struct MyType1* MyType1Handle; 

यह सी में काम नहीं किया खाली structs के बाद से अवैध सी कोड है। मैं निश्चित रूप से एक डमी सदस्य के साथ अपनी संरचना का विस्तार कर सकता था, लेकिन ऐसा लगता है कि ऐसा करने का एक बेहतर तरीका होना चाहिए।

तो मेरे सवाल करने पर निर्भर करता:

कैसे आप आमतौर पर सबसे अधिक संगत रास्ते में प्रकार इस तरह का उल्लेख करूं?

उत्तर

12

आप कैसे माइक्रोसॉफ्ट को परिभाषित करता है यह WinAPI हैंडल (winnt.h) यह वास्तव में इस तरह दिखता है पर नज़र डालें तो:

#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name 
तो

:

struct HWND__ { int unused; }; typedef struct HWND__ *HWND 

वास्तव में वे इस के लिए एक मैक्रो है। ऐसा करने के लिए यह एक आम प्रथा प्रतीत होता है। दुर्भाग्यवश मैं इसे छोड़कर एक और सुझाव नहीं दे सकता, जिसे आप पहले से ही का उल्लेख करते हैं, लेकिन मुझे उम्मीद है कि यह आपकी मदद करता है।

+0

जवाब के लिए धन्यवाद। ऐसा लगता है कि मैं इस समस्या में कम से कम पहली बार नहीं हूं :) – Laserallan

+0

यहां एक अंतर यह है कि सार्वजनिक शीर्षकों में, हैंडल प्रकार एक ठोस प्रकार का संदर्भ देता है। नकली संरचना पूरी तरह से परिभाषित है। बेशक, कार्यान्वयन में उन फ़ाइलों को शामिल करते समय वे DECLARE_HANDLE को अलग-अलग परिभाषित करते हैं। – RBerteig

3

मुझे लगता है कि तुम सिर्फ घोषणा कर सकते हैं, लेकिन नहीं परिभाषित करते हैं, स्रोत संरचनाओं:

struct MyType1;

टाइपपीफ संरचना MyType1 * MyType1 हैंडल;

8

एक अपारदर्शी संरचना का उपयोग करें। सी में लाइब्रेरी में इंटरफेस को परिभाषित करते समय यह कई मामलों में एक अच्छा विचार है: यह मॉड्यूलरिटी में सुधार करता है, अनावश्यक विस्तार छुपाता है

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

सी मानक पुस्तकालय, और कई अन्य, पहले से ही इस दृष्टिकोण का उपयोग करते हैं, इसलिए यह परिचित होना चाहिए। Cannonical उदाहरण FILE * का उपयोग है: fopen() संरचना बनाता है और प्रारंभ करता है और इसे पॉइंटर देता है, fclose() इसे साफ़ करता है और इसे जारी करता है और अन्य सभी I/o कार्यों को FILE * में पारित होने से अपना संदर्भ मिलता है।

+0

टाइपपीफ में छिपाने वाले पॉइंटर्स अक्सर परेशानी के लिए कहते हैं (त्रुटि संदेश की बात करते हुए जो पॉइंटर्स के बारे में कुछ बताते हैं भले ही आपका प्रोग्राम उनका उपयोग न करे या इसके विपरीत); तो ऊपर एचडब्ल्यूएनडी दृष्टिकोण मैं वास्तव में सिफारिश नहीं कर सकता; संरचना-परिभाषा-न उजागर काम बेहतर है। सी ++ के लिए, क्योंकि कक्षा परिभाषा को काम करने के लिए कक्षा परिभाषा उपलब्ध कराई जानी चाहिए, "डी-पॉइंटर" दृष्टिकोण यहां सबसे अच्छा काम करेगा। – user502515

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