DLL descriptor class slicing

I have a Visual Studio 2008 C ++ project where I create a DLL with the C interface. I define two types of callback functions: regular and advanced, which provides additional data.

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 ); 

I maintain state with a UserData structure. Since I have two types of callbacks, I get two structures:

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

How to reconcile my API with two different UserData structures without creating separate EX versions of each function? Is there a way to template a callback? Or create a base class of user data?

 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; } 
+7
source share
1 answer

Not elegant, but it will work:

  • The structures of UserData and UserDataEx identical, except for pointer types. Combine these two structures into one and replace the FARPROC callback pointer type. You will need to swing back and forth when setting up and retrieving these function pointers.
  • You also need to add some explicit type information to your structure to indicate whether to send a callback to the standard version or the "Ex" version. For example, you can add the flags field and set the USES_EXTENDED_CALLBACK flag.
+1
source

All Articles