F:\>dumpbin -exports yhybReckoning_his.dll Microsoft (R) COFF/PE Dumper Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file yhybReckoning_his.dllFile Type: DLL Section contains the following exports for yhybReckoning.dll 00000000 characteristics 3DF2FCD4 time date stamp Sun Dec 08 16:03:32 2002 0.00 version 1 ordinal base 4 number of functions 4 number of names ordinal hint RVA name 1 0 00001023 _AutoDial@0 2 1 00001014 _DataDown_rs@12 3 2 00001019 _DataDown_sp@12 4 3 0000101E _DataUpload@12 Summary 4000 .data 1000 .idata 3000 .rdata 2000 .reloc 29000 .text
用您说第二种方法报错信息如下: Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.大概说的意思是:这种定义不符合函数的修饰约定规则查了下<<MFC深入浅出>> 是这样说的: _stdcall 按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于“C”函数或者变量,修饰名以下划线为前缀,然后是函数名,然后是符号“@”及参数的字节数,如函数int func(int a, double b)的修饰名是_func@12。对于“C++”函数,则有所不同。这种规则正符合C导出的函数修改规则 即上面代码中的:"_DataUpload@12"经过查阅其它资料看到设置"提交栈的大小"的设置: 在VS 2008中工程属性>>配置属性>>链接器>>系统>>将堆栈提交大小设置为5000000(字节), 运行,依旧报错.卸载VS2008装上VS6 按上上面的设置,重新生成 顺利通过...虽然通过了,但还是对两种环境下出现在的结果不一样存有疑惑!! 如有高人能解释清楚,洗耳恭听!
花了我两个小时…… 你的DLL 导出是怎么样的 ? int __declspec(dllexport) Cpp(int a,int b) {return a+b;} int __declspec(dllexport) __stdcall CppStdcall(int a,int b) {return a+b;} extern "C" int __declspec(dllexport) CType(int a,int b) {return a+b;} extern "C" int __declspec(dllexport) __stdcall CTypeStdcall(int a,int b) {return a+b;} int __declspec(dllexport) __cdecl CppCdecl(int a,int b) {return a+b;} extern "C" int __declspec(dllexport) __cdecl CTypeCdecl(int a,int b) {return a+b;}这里我导出了6个函数 然后用dumpbin 查看(dbg版本 releas开了优化导出的名称不大对劲)-----------------------------------------------------------------Dump of file D:\Backup\我的文档\Visual Studio 2005\Projects\Virus\debug\VrServerDll.dllFile Type: DLL Section contains the following exports for VrServerDll.dll 00000000 characteristics 4BDBF26C time date stamp Sat May 01 17:20:44 2010 0.00 version 1 ordinal base 6 number of functions 6 number of names ordinal hint RVA name 1 0 00011118 ?Cpp@@YAHHH@Z = @ILT+275(?Cpp@@YAHHH@Z) 2 1 0001108C ?CppCdecl@@YAHHH@Z = @ILT+135(?CppCdecl@@YAHHH@Z) 3 2 000111BD ?CppStdcall@@YGHHH@Z = @ILT+440(?CppStdcall@@YGHHH@Z) 4 3 000110D7 CType = @ILT+210(_CType) 5 4 000110A0 CTypeCdecl = @ILT+155(_CTypeCdecl) 6 5 0001117C _CTypeStdcall@8 = @ILT+375(_CTypeStdcall@8) Summary 1000 .data 1000 .idata 2000 .rdata 1000 .reloc 1000 .rsrc 4000 .text 10000 .textbss-------------------------------------------------------------------- 未加extern "C"的导出的函数名称是C++样式的 而加了extern "C"导出的是C样式 加了__cdecl和没加是一摸一样的 而且函数名称就是简单的函数名 而加了__stdcall关键字修饰的函数名则是像你说的那样的命名方式加了__stdcall关键字的调用的时候要声明__stdcall 没有加(默认)的或者是__cdecl的(其实一回事)则不需要,可以直接调用
确定stdcall调用约定生成的函数名为_DataUpload@12?
GetProcAddress(hInst,MAKEINTRESOURCEA(1));
F:\>dumpbin -exports yhybReckoning_his.dll
Microsoft (R) COFF/PE Dumper Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file yhybReckoning_his.dllFile Type: DLL Section contains the following exports for yhybReckoning.dll 00000000 characteristics
3DF2FCD4 time date stamp Sun Dec 08 16:03:32 2002
0.00 version
1 ordinal base
4 number of functions
4 number of names ordinal hint RVA name 1 0 00001023 _AutoDial@0
2 1 00001014 _DataDown_rs@12
3 2 00001019 _DataDown_sp@12
4 3 0000101E _DataUpload@12 Summary 4000 .data
1000 .idata
3000 .rdata
2000 .reloc
29000 .text
extern "C" DllExport LPSTR DataUpload(LPSTR RecordStr,LPSTR UploadLSH,LPSTR Rec_Data_Up)
调用:
typedef LPSTR (__stdcall *DataUpload_)(LPSTR,LPSTR,LPSTR);ms c++编译器默认C调用为pascal方式的,即你导出时是普通c调用,使用时却用__stdcall方式,导致栈错误。解决方法:统一调用方式。修改导出为:
extern "C" DllExport LPSTR __stdcall DataUpload(LPSTR RecordStr,LPSTR UploadLSH,LPSTR Rec_Data_Up)
或者修改声明为:
typedef LPSTR (*DataUpload_)(LPSTR,LPSTR,LPSTR);
用您说第二种方法报错信息如下:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.大概说的意思是:这种定义不符合函数的修饰约定规则查了下<<MFC深入浅出>> 是这样说的:
_stdcall 按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于“C”函数或者变量,修饰名以下划线为前缀,然后是函数名,然后是符号“@”及参数的字节数,如函数int func(int a, double b)的修饰名是_func@12。对于“C++”函数,则有所不同。这种规则正符合C导出的函数修改规则 即上面代码中的:"_DataUpload@12"经过查阅其它资料看到设置"提交栈的大小"的设置:
在VS 2008中工程属性>>配置属性>>链接器>>系统>>将堆栈提交大小设置为5000000(字节),
运行,依旧报错.卸载VS2008装上VS6 按上上面的设置,重新生成 顺利通过...虽然通过了,但还是对两种环境下出现在的结果不一样存有疑惑!! 如有高人能解释清楚,洗耳恭听!
int __declspec(dllexport) __stdcall CppStdcall(int a,int b) {return a+b;}
extern "C" int __declspec(dllexport) CType(int a,int b) {return a+b;}
extern "C" int __declspec(dllexport) __stdcall CTypeStdcall(int a,int b) {return a+b;}
int __declspec(dllexport) __cdecl CppCdecl(int a,int b) {return a+b;}
extern "C" int __declspec(dllexport) __cdecl CTypeCdecl(int a,int b) {return a+b;}这里我导出了6个函数 然后用dumpbin 查看(dbg版本 releas开了优化导出的名称不大对劲)-----------------------------------------------------------------Dump of file D:\Backup\我的文档\Visual Studio 2005\Projects\Virus\debug\VrServerDll.dllFile Type: DLL Section contains the following exports for VrServerDll.dll 00000000 characteristics
4BDBF26C time date stamp Sat May 01 17:20:44 2010
0.00 version
1 ordinal base
6 number of functions
6 number of names ordinal hint RVA name 1 0 00011118 ?Cpp@@YAHHH@Z = @ILT+275(?Cpp@@YAHHH@Z)
2 1 0001108C ?CppCdecl@@YAHHH@Z = @ILT+135(?CppCdecl@@YAHHH@Z)
3 2 000111BD ?CppStdcall@@YGHHH@Z = @ILT+440(?CppStdcall@@YGHHH@Z)
4 3 000110D7 CType = @ILT+210(_CType)
5 4 000110A0 CTypeCdecl = @ILT+155(_CTypeCdecl)
6 5 0001117C _CTypeStdcall@8 = @ILT+375(_CTypeStdcall@8) Summary 1000 .data
1000 .idata
2000 .rdata
1000 .reloc
1000 .rsrc
4000 .text
10000 .textbss--------------------------------------------------------------------
未加extern "C"的导出的函数名称是C++样式的
而加了extern "C"导出的是C样式
加了__cdecl和没加是一摸一样的 而且函数名称就是简单的函数名
而加了__stdcall关键字修饰的函数名则是像你说的那样的命名方式加了__stdcall关键字的调用的时候要声明__stdcall
没有加(默认)的或者是__cdecl的(其实一回事)则不需要,可以直接调用