文档章节

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

李勇2
 李勇2
发布于 2015/03/02 09:38
字数 632
阅读 24
收藏 1
点赞 0
评论 0

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

粉丝 45
博文 188
码字总数 62209
作品 0
广州
程序员
函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)

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

AlphaJay ⋅ 2010/08/20 ⋅ 1

__declspec(dllimport)和__declspec(dllexport)的区别,以及有关c/c++调用约定

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

AlphaJay ⋅ 2010/08/20 ⋅ 0

dll的概念 dll导出变量 函数 类 (转)

1、 DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数、变量或类。这些可以直接拿来使用。 静态链接库与动态链接库的区别: (1)静态链接库与动态链接库都是共...

长平狐 ⋅ 2012/10/08 ⋅ 0

BCB 编写 DLL 终极手册

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

狂斩一条龙 ⋅ 2011/07/31 ⋅ 0

动态链接库

一:DLL基础 Windows API的所有函数都包含在dll中 Windows最重要的三个dll: 为什么要使用dll? DLL中通常没有支持处理消息循环或创建窗口的代码 对于一个DLL, 必须要为链接程序设定/DLL开关...

牛肉圆粉不加葱 ⋅ 2014/07/10 ⋅ 0

解析__cdecl,__fastcall, __stdcall 的不同

在函数调用过程中,会使用堆栈,这三个表示不同的堆栈调用方式和释放方式。 比如说cdecl,它是标准的c方法的堆栈调用方式,就是在函数调用时的参数压入堆栈是与函数的声明顺序相反的,其它两...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

隐式链接无.LIB动态链接库

由于我们经常要调用一些第三方厂商或其他编译器编写的动态链接库,但是一般都不提供源文件或.lib文件,而作为VC隐式链接到DLL(implicitly link to the DLL)调用,这些却是必需的。本文将主...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

C/C++函数调用的几种方式

我们知道,调用函数时,计算机常用栈来存放函数执行需要的参数,由于栈的空间大小是有限的,在windows下栈是向低地址扩展的数据结构,是一块连续的内存区域。这句话的意思是栈顶的地址和栈的...

cosmos180 ⋅ 2012/04/26 ⋅ 0

C++ 的 C 方式编译和 C 链接约定

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

晨曦之光 ⋅ 2012/05/23 ⋅ 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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Jenkins实践3 之脚本

#!/bin/sh# export PROJ_PATH=项目路径# export TOMCAT_PATH=tomcat路径killTomcat(){pid=`ps -ef | grep tomcat | grep java|awk '{print $2}'`echo "tom...

晨猫 ⋅ 今天 ⋅ 0

Spring Bean的生命周期

前言 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: Spring 只帮我们管理单例模...

素雷 ⋅ 今天 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

实验楼—MySQL基础课程-挑战3实验报告

按照文档要求创建数据库 sudo sercice mysql startwget http://labfile.oss.aliyuncs.com/courses/9/createdb2.sqlvim /home/shiyanlou/createdb2.sql#查看下数据库代码 代码创建了grade......

zhangjin7 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部