2012-03-16 14 views
7

स्लाइसिंग मेरे पास एक विजुअल स्टूडियो 2008 सी ++ प्रोजेक्ट है जहां मैं एक सी इंटरफेस के साथ एक डीएलएल बना रहा हूं। मैं दो प्रकार के कॉलबैक फ़ंक्शंस को परिभाषित करता हूं: एक नियमित और विस्तारित जो अतिरिक्त डेटा प्रदान करता है।एक डीएलएल हैंडल वर्ग

struct Foo { 
    char a[ MAX_A ]; 
    char b[ MAX_B ]; 
    char c[ MAX_C ]; 
}; 
struct FooEx { 
    char a[ MAX_A ]; 
    char b[ MAX_B ]; 
    char c[ MAX_C ]; 
    char d[ MAX_D ]; 
}; 
typedef void (CALLBACK *USERCALLBACK)(const Foo&, DWORD); 
typedef void (CALLBACK *USERCALLBACK_EX)(const FooEx&, DWORD); 

मैं UserData संरचना के साथ राज्य को बनाए रखता हूं। क्योंकि मैं कॉलबैक के दो प्रकार के, मैं दो संरचनाओं के साथ अंत:

struct UserData { 
    DWORD user; 
    int zoo; 
    std::string bar; 
    USERCALLBACK callback; 
}; 

struct UserDataEx { 
    DWORD user; 
    int zoo; 
    std::string bar; 
    USERCALLBACK_EX callback; 
}; 

कैसे मैं हर समारोह के अलग पूर्व संस्करणों बनाने के बिना दो अलग UserData संरचनाओं होने के साथ मेरी एपीआई सामंजस्य करते हैं? क्या कॉलबैक को टेम्पलेट करने का कोई तरीका है? या उपयोगकर्ता डेटा का बेस-क्लास बनाएं?

DECLARE_HANDLE(HMYAPI); 

// this function is agnostic of the callback type 
MY_API HMYAPI MyAPI_Create() 
{ 
    return (HMYAPI)new UserData(); 
} 

// This function does not directly use the callback type, but may need to know it to properly deallocate the UserData structure. 
MY_API void MyAPI_Close(HMYAPI handle) 
{ 
    delete reinterpret_cast< UserData* >(handle); 
} 

// this function needs to know about the different callback types 
MY_API void MyAPI_Register(HMYAPI handle, USERCALLBACK cb, DWORD user) 
{ 
    UserData* ud = reinterpret_cast< UserData* >(handle); 
    ud->cb = cb; 
    ud->user = user 
} 

// this function needs to know about the different callback types 
MY_API void MyAPI_RegisterEX(HMYAPI handle, USERCALLBACK_EX cb, DWORD user) 
{ 
    UserData* ud = reinterpret_cast< UserData* >(handle); 
    ud->cb = cb; 
    ud->user = user 
} 

// this function is agnostic of the callback type 
MY_API void Foo(HMYAPI handle, int x) 
{ 
    UserData* ud = reinterpret_cast< UserData* >(handle); 
    ud->bar = "Foo"; 
    ud->zoo = x; 
} 
+11

http://www.partow.net/programming/templatecallback/index.html#VariableArgumentDerivative – Flot2011

उत्तर

1

सुरुचिपूर्ण नहीं है, लेकिन यह काम करेगा:

  • आपका UserData और UserDataEx संरचनाओं सूचक प्रकार से समान अन्य कर रहे हैं। उन दो संरचनाओं को एक साथ संयोजित करें और कॉलबैक सूचक प्रकार को FARPROC के साथ बदलें। उन फ़ंक्शन पॉइंटर्स को सेट और पुनर्प्राप्त करते समय आपको आगे और आगे बढ़ना होगा।
  • आपको मानक संरचना या "एक्स" संस्करण में कॉलबैक डालने के लिए निर्दिष्ट करने के लिए आपको अपनी संरचना में किसी प्रकार की स्पष्ट प्रकार की जानकारी जोड़ने की आवश्यकता होगी। उदाहरण के लिए, आप flags फ़ील्ड जोड़ सकते हैं और USES_EXTENDED_CALLBACK ध्वज सेट कर सकते हैं।
+0

मुझे लगता है कि शायद मुझे यह करना होगा। मैं टेम्पलेट्स के साथ एक अच्छा सुरुचिपूर्ण समाधान की उम्मीद कर रहा था। लेकिन, यह एकमात्र समाधान हो सकता है क्योंकि ऑब्जेक्ट को तुरंत चालू करने के बाद आप प्रकार को नहीं बदल सकते हैं। – PaulH

+0

ध्यान दें कि 'Foo' और' FooEx' * मान * द्वारा पारित किया जा रहा है। पते से उन्हें पास करने से कॉलबैक मर्ज करना आसान हो जाएगा। –

+0

@ रेमंड चेन - काफी सही। मैंने कोड अपडेट किया है। – PaulH

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