浏览 6083 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-01-22
大家都应该知道,函数调用都有修饰符,有__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等正确调用呢?奇怪啊。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-01-24
似乎在vc里是这样,lib里的名字是有修饰符的,但lib中函数对应的dll中的函数没有。
|
|
返回顶楼 | |
发表时间:2010-01-26
最后修改:2010-01-28
刚才用dumpbin看了一下,果然lib都有修饰,而dll则没有修饰。
|
|
返回顶楼 | |
发表时间:2010-02-25
... ...
加个extern "C"修饰就OK了嘛。。。 |
|
返回顶楼 | |