Ошибка соглашения о вызовах с DLL - PullRequest
2 голосов
/ 22 января 2012

Я создаю DLL с MinGW, 32-битный режим для приложения (PCSX), для которого у меня есть источник. Я следую указаниям другого источника модулей.

Произошла ошибка:

Ошибка проверки времени выполнения # 0 - значение ESP не было должным образом сохранено при вызове функции. Обычно это является результатом вызова функции, объявленной с одним соглашением о вызовах с указателем функции, объявленным с другим соглашением о вызовах.

PSEgetLibName вызывается нормально и возвращает правильный результат. PADinit выдает вышеуказанную ошибку.

// sucess, everything configured, and went OK.
#define PSE_PAD_ERR_SUCCESS         0

main.h

long PADinit(long flags);

main.c

long PADinit(long flags) {
    return PSE_PAD_ERR_SUCCESS;
}
char *PSEgetLibName(void) {
    return _("PSX-U");
}

Makefile:

# Build for Windows under MinGW
#MINGWDBG= -DDEBUG -O0
MINGWDBG= -DNDEBUG -O2
#MINGWOPT= -W -Wall -mthreads -Wl,--subsystem,console $(MINGWDBG) -DHAVE_STDINT
MINGWOPT= -W -Wall -mthreads -Wl,--subsystem,windows $(MINGWDBG)
mingw:
    windres win32\res.rc win32\res.o
    gcc $(MINGWOPT) mongoose.c main.c -lws2_32 \
        -shared -Wl,--out-implib=$(PROG).lib -o $(PROG).dll
    gcc $(MINGWOPT) mongoose.c main.c win32\res.o -lws2_32 -ladvapi32 \
        -o $(PROG).exe

Я попытался объявить функцию с __stdcall и __cdecl, так как казалось, что это имеет значение для этой ошибки, но это не изменит результат.

Edit: Код вызова:

plugins.h

typedef long (CALLBACK* PADinit)(long);
...
extern PADinit             PAD1_init;

plugins.c

    ret = PAD1_init(1);

Полный исходный код здесь (для PCSX): http://pcsxr.codeplex.com/SourceControl/list/changesets

Ответы [ 2 ]

2 голосов
/ 23 января 2012

Я обнаружил, что mingw нужно передать параметр компоновщику (-Wl, - add-stdcall-alias), и использование __stdcall окончательно решило проблему!

http://www.mingw.org/wiki/Visual_Basic_DLL

2 голосов
/ 22 января 2012

Вы должны придерживаться макроса CALLBACK, как это делается в заголовочном файле плагинов и в других плагинах в исходном коде, на который вы ссылаетесь.

Он расширяется до __attribute__((__stdcall__)) с помощью mingw /GCC 4.5.Поместите его как в заголовок, так и в файл реализации.

long CALLBACK PADinit(long flags);
long CALLBACK PADinit(long flags) {
    return PSE_PAD_ERR_SUCCESS;
}

Вы должны аннотировать все функции обратного вызова, независимо от того, работают они или нет.

...