нарезать класс дескриптора DLL - PullRequest
7 голосов
/ 17 марта 2012

У меня есть проект Visual Studio 2008 C ++, где я создаю DLL с интерфейсом C. Я определяю два типа функций обратного вызова: обычные и расширенные, которые предоставляют дополнительные данные.

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

Как мне согласовать мой API с двумя UserData структурами без создания отдельных версий EX каждой функции? Есть ли способ шаблонизировать обратный вызов? Или создать базовый класс пользовательских данных?

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

1 Ответ

1 голос
/ 17 марта 2012

Не элегантно, но будет работать:

  • Ваши UserData и UserDataEx структуры идентичны, кроме типов указателей.Объедините эти две структуры в одну и замените тип указателя обратного вызова на FARPROC.При установке и извлечении этих указателей функций вам придется приводить туда и обратно.
  • Вам также необходимо добавить некоторую информацию о явном типе в вашу структуру, чтобы указать, следует ли приводить обратный вызов к стандартной версииили версия «Ex».Например, вы можете добавить поле flags и установить флаг USES_EXTENDED_CALLBACK.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...