论坛首页 编程语言技术论坛

C的修饰符__stdcall在导出Dll时候的问题

浏览 6083 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-01-22  
C
近来烦一件事。

大家都应该知道,函数调用都有修饰符,有__cdecl,__stdcall,__fastcall等等,不同修饰符意味着不同的参数出栈方式以及不同的函数名称变化。
对于C语言,默认是__cdecl,但如果我们要做DLL需要其它语言例如Delphi、VB等调用,通常都建议声明为__stdcall。win32的api基本都是__stdcall方式(就是那个WINAPI宏)。

问题就出在这个stdcall了。对于VC来说,__cdecl修饰的函数,在DLL的导出名字一般是没有变化的,但对于__stdcall就会做一些改变,在前面加一个下划线,后面再补上一个“@”,再加上参数的字节长度总和。

例如,对于函数 int add(int a, int b),如果int __cdecl add(int a, int b),在DLL的导出名字还是“add”,但如果是int __stdcall add(int a, int b),在DLL的导出名字就是“_add@8”(查看导出名字可以用VC自带的dumpbin命令,方法是“dumpbin /exports aaa.dll”)。

好了,说了一大堆废话,开始进主题啦。

开始的时候,我做了一个test.dll,例如包含一个导出的函数 int __stdcall build(int n)。
在delphi的时候,如果用
function build(n:Integer): integer; stdcall; external 'test.dll' name 'build';
这种声明方式的话,导入会出错,因为找不到build这个函数,这里的build已经改成名字是_build@4。当然,如果我们直接写“external 'test.dll' name '_build@4';”应该是没有问题的。不过不爽。为什么win api的函数就没有这些乱七八糟的东西?

后来在网上找了一遍,写了一个def文件。

LIBRARY   test.dll

EXPORTS
build


这样生成的dll的导出名字就没有那些乱七八糟的修饰符了。不过这个时候又轮到C这边有问题了。原因是C这边在链接的时候找不到_build@4这个函数。真是晕倒,两边不讨好。

我就觉得奇怪,怎么win api的函数,即没有那些修饰符,但又可以让delphi、C、VB等正确调用呢?奇怪啊。

   发表时间:2010-01-24  
似乎在vc里是这样,lib里的名字是有修饰符的,但lib中函数对应的dll中的函数没有。
0 请登录后投票
   发表时间:2010-01-26   最后修改:2010-01-28
刚才用dumpbin看了一下,果然lib都有修饰,而dll则没有修饰。

0 请登录后投票
   发表时间:2010-02-25  
... ...
加个extern "C"修饰就OK了嘛。。。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics