用DLL调用约定错误

时间:2012-01-22 15:36:02

标签: c gcc dll shared-libraries

我正在使用MinGW构建DLL,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");
}

生成文件:

# 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声明该功能,因为它似乎对此错误很重要,但它不会更改结果。

编辑: 代码致电:

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 个答案:

答案 0 :(得分:2)

您应该坚持使用CALLBACK宏,就像在插件头文件和您引用的源代码中的其他插件中一样。

使用mingw / GCC 4.5扩展到__attribute__((__stdcall__))。把它放在标题和实现文件中。

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

您应该注释所有类似的回调函数,无论它们是否正常工作。

答案 1 :(得分:2)

我发现需要将mingw传递给链接器(-Wl, - add-stdcall-alias)并使用__stdcall最终解决了这个问题!

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