Добавление stdcall к функции обратного вызова приводит к несоответствию аргументов [GNU]

Я пытаюсь добавить соглашение о вызовах stdcall в свою скомпилированную GNU DLL.

Вот мой код:

typedef void (__stdcall * CTMCashAcceptCallback) (
    const struct CTMEventInfo,
    const struct CTMAcceptEvent );

Это было вызвано этой функцией:

LIBCTMCLIENT_FUNC void ctm_add_cash_accept_event_handler(CTMCashAcceptCallback);

куда:

#define LIBCTMCLIENT_FUNC LIBCTMCLIENT_C_LINKAGE __declspec(dllexport) __stdcall

Проблема в том, что он дает мне эту заметку:

примечание: ожидается «CTMCashAcceptCallback», но аргумент имеет тип «void (*) (const struct CTMEventInfo, const struct CTMAcceptEvent)»

Когда я удаляю __stdcall или заменяю его на __cdecl, он не дает этой информации. Нельзя ли использовать stdcall при компиляции через GNU или может я не так делаю?


person aljochimera    schedule 18.03.2015    source источник


Ответы (1)


Пользовательский код должен явно указать компилятору, что его собственная функция (та, которую вы не показали) должна быть __stdcall, если это то, что ожидает DLL. Что-то вроде

__stdcall myCTMCashAccept (
   const struct CTMEventInfo,
   const struct CTMAcceptEvent)
{
  //...
}
// ...
  ctm_add_cash_accept_event_handler(myCTMCashAccept);

должно сработать.

Помните, что #define LIBCTMCLIENT_FUNC, который вы показали, относится к соглашению для пользовательского кода, вызывающего DLL; в то время как обратный вызов с его typedef работает иначе: это DLL, вызывающая пользовательский код. Им не обязательно использовать одни и те же соглашения (хотя когда они это делают, становится понятнее); поэтому, если ваш пользовательский код, вероятно, будет использовать код __cdecl (возможно, потому, что он уже существует), вам следует удалить __stdcall из typedef (и это тоже должно работать).

person AntoineL    schedule 18.03.2015
comment
Я не думаю, что CTMCashAcceptCallback имеет другие детали кода, потому что это сигнатура обратного вызова (указатель функции). - person aljochimera; 19.03.2015
comment
@aljochimera: я имел в виду функцию, предоставленную некоторым пользователем (в отличие от библиотеки, которая является DLL), тип которой совместим с функциями, на которые указывают указатели CTMCashAcceptCallback. Извините за путаницу между обратными вызовами (функциями) и объектами CTMCashAcceptCallback, которые являются указателями на функции. - person AntoineL; 19.03.2015
comment
спасибо @AntoineL! вы правы, после добавления stdcall в функцию сообщение больше не отображается. - person aljochimera; 20.03.2015