文档章节

extern "c" 动态链接库符号表导出问题 以及函数参数压栈顺序

李勇2
 李勇2
发布于 2015/03/02 09:38
字数 632
阅读 26
收藏 1

c语言编译的动态链接库中,导出的符号名字就是 源代码中的相应的名字;

例如函数 void test(){} 导出的符号名字 就是 test


但是对于c++ 来讲不是这样, c++ 有类, 名字空间, 函数重载, 导致多个不同的对象可能使用一个相同的名字, 这样必须由编译器来生成全局的唯一名字;

这种生成的方式 没有标准化, 所以 window上的vc 编译器可能生成一种名字, linux上的gcc 可能生成一种名字, mingw 可能也会生成一种名字;

因此不同编译器生成的C++动态库, 从符号名字上来讲,不兼容。


但是如果需要从C++库导出某些名字 使得大家都认识该怎么做呢?

源代码中写下:

extern "c"{

   void test();

}

将会生成 标准的c符号名字, 也就是 test, 这样所有人都会认识这个符号了!

当然要注意一点 所有声明该符号的位置 不能出现在名字空间中, 否则 仍旧生成 C++类型的符号名字。



标准c中定义了函数的参数的压栈和出栈相关问题: 压栈从右向左压入参数;而当函数返回的时候, 由调用者负责清理堆栈, 弹出 相应的参数

也就是被调用者 直接return, 调用者再清理 堆栈顶部指针, 这样实现printf 函数就比较方便了(可变长度参数, 被调用者不用关心参数的数量)


但是win32中, 有一种windows专用的stdcall方法, 参数也是从右向左压入, 但是 函数返回的时候是由被调用者清理堆栈

也就是被调用者先拿到返回地址, 在设置堆栈顶部指针, 最后返回(被调用者需要关心参数的数量)



这些是windows 需要的东西:

因此在写win32程序的时候 如果需要 采用标准的 c参数处理方式, 就需要显示的告诉 编译器;

__cdecl 标准c的参数管理方式                __stdcall windows的参数管理方式



主要用于dll说明参数的管理方式的:

__declspec(dllexport)用于导出 该动态库 的标准c方式的函数

__declspec(dllimport) 用于一个动态库 依赖于 另一个动态库的函数
 






本文转载自:http://blog.csdn.net/liyong748/article/details/7551650

共有 人打赏支持
李勇2

李勇2

粉丝 46
博文 189
码字总数 62209
作品 0
广州
程序员
私信 提问
函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)

关于函数的调用规则(调用约定),大多数时候是不需要了解的,但是如果需要跨语言的编程,比如VC写的dll要delphi调用,则需要了解。 microsoft的vc默认的是cdecl方式,而windows API则是std...

AlphaJay
2010/08/20
0
1
__declspec(dllimport)和__declspec(dllexport)的区别,以及有关c/c++调用约定

DLL可以使用两种方法将公共符号导入到应用程序中或从 DLL 导出函数: 生成 DLL 时使用模块定义 (.DEF) 文件。 在主应用程序的函数定义中使用 declspec(dllimport) 或 declspec(dllexport) 关...

AlphaJay
2010/08/20
0
0
__cdecl __stdcall

1.如果函数func是cdecl(默认调用方式),调用时情况如下 int main() { //参数从右到左压栈 push 4 push 3 push 2 push 1 call func add esp 0x10 //调用者恢复堆栈指针esp,4个参数的大小是0...

ryany
2011/03/21
0
0
BCB 编写 DLL 终极手册

一. 编写 DLL File/New/Dll 生成 Dll 的向导,然后可以添加导出函数和导出类 导出函数:extern "C" declspec(dllexport) ExportType FunctionName(Parameter) 导出类:class declspec(dllexp...

狂斩一条龙
2011/07/31
0
0
C++ 的 C 方式编译和 C 链接约定

原文:C++ 的 C 编译和链接方式 (VC) 作者:Breaker C++ 与 C 的编译方式 所有的 C 程序都是 C++ 程序,而所有的 C++ 编译器都是 C 编译器(几乎所有),兼容 C99 标准 wiki: C99。一些编译器...

晨曦之光
2012/05/23
952
0

没有更多内容

加载失败,请刷新页面

加载更多

linux之自定义命令

本人使用的是ubuntu系统,不喜欢建各种桌面快捷链接,但是每次启动个软件,去查找又麻烦,所以自定义了命令,来快捷的启动应用: 1、修改/etc/bash.bashrc,在文件末尾,加上如下List-1中的内...

克虏伯
8分钟前
0
0
linux基础

系统安全 sudo su chmod setfacl 进程管理 w top ps kill pkill pstree killall 用户管理 id usermod useradd groupad userdel 文件系统 mount umount fsck df du 网络应用 curl telnet mail......

关元
10分钟前
0
0
Caffe-源码分析(一)

CHECK_X函数,用于比较两个blob之间的值 CHECK_EQ(x,y)<<"x!=y",EQ即equation,意为“等于”,当x!=y时,函数打印出x!=y。 CHECK_NE(x,y)<<"x=y",NE即not equation,意为“不等于”,,...

Pulsar-V
10分钟前
0
0
三星Galaxy S10可能会配备TOF 3D摄像头

12月3日消息,据Phone Arena报道,三星Galaxy S10可能会配备TOF 3D摄像头。 Phone Arena报道称三星Galaxy S10一共有五颗摄像头(前置双摄+后置三摄),而5G版本的Galaxy S10后置四颗摄像头,...

问题终结者
33分钟前
9
0
fabric增删改查Mac

备份1.3版本,重新下载1.1版本到fabric文件夹 /opt/gopath/src/github.com/hyperledger/fabric -> /opt/gopath/src/github.com/hyperledger/fabric1.3 新建/opt/gopath/src/github.com/hype......

八戒八戒八戒
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部