Добавянето на 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