Как выполнить приведение указателя на функцию без определения типа?

Я использую ACE для получения функций из динамически загружаемой библиотеки DLL. Функция symbol () ниже возвращает указатель void, который я должен вернуть к исходному состоянию.

typedef cBase * (_cdecl *typeCreateManager)( void );

// ...

ACE_DLL * m_pAceDll = new ACE_DLL;
m_pAceDll->open( "NameOfDll.dll" );

cBase * (_cdecl *pfunc)( void ); // declaration of function pointer
// can be replaced by "typeCreateManager pfunc;"

pfunc = (typeCreateManager)m_pAceDll->symbol("?createManager@@YAPAVcBase@@XZ");
// can be replaced by ???

cBase * pObject = (*pfunc)();

m_pAceDll->close();

Два вопроса:

  1. Какое преобразование C ++ подходит вместо преобразования типа C? Статичный или переосмысленный?

  2. Могу ли я опустить typedef в приведении? Каков правильный синтаксис? Я не хочу, чтобы он был виден везде, где используется моя DLL. Поскольку мне это нужно только в небольшом количестве мест в коде, я бы хотел удалить typedef.


person Fabian    schedule 21.04.2015    source источник
comment
См. указатели-функции-приведение-в-c   -  person WaeCo    schedule 21.04.2015
comment
Что касается пункта 2 и придерживаясь стиля C, я бы предположил (cBase * (_cdecl (*))( void )) или просто (cBase * (_cdecl *)( void )).   -  person Peter - Reinstate Monica    schedule 21.04.2015


Ответы (2)


Какое преобразование C ++ подходит вместо преобразования типа C? Статичный или переосмысленный?

Вам нужно reinterpret_cast, чтобы преобразовать указатель объекта (включая void*) в указатель функции.

Могу ли я опустить typedef в приведении?

Если у вас есть указатель правильного типа, вы можете указать тип указателя, а не имя типа:

cBase * (_cdecl * pfunc)();
pfunc = reinterpret_cast<decltype(pfunc)>(...);

или вы можете вывести тип указателя из выражения приведения:

auto pfunc = reinterpret_cast<cBase*(_cdecl *)()>(...);

но вам нужно где-то указать тип функции, и, вероятно, будет более ясным и менее подверженным ошибкам использовать подходящий typedef как для приведения типов, так и для объявлений переменных.

person Mike Seymour    schedule 21.04.2015

Другой способ сделать это - использовать союзы.

union{
    void *data;
    cBase* (*pfunc)(void);
}converter;

//...

converter.data = m_pAceDll->symbol("?createManager@@YAPAVcBase@@XZ");
cBase *base = converter.pfunc();
person thefunkyjunky    schedule 21.04.2015