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

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

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


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

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

所以不一样编译器生成的C++动态库, 从符号名字上来说,不兼容。指针


可是若是须要从C++库导出某些名字 使得你们都认识该怎么作呢?对象

源代码中写下:
编译器

extern "c"{编译

   void test();
test

}
import

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

固然要注意一点 全部声明该符号的位置 不能出如今名字空间中, 不然 仍旧生成 C++类型的符号名字。



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

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


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

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



这些是windows 须要的东西:

所以在写win32程序的时候 若是须要 采用标准的 c参数处理方式, 就须要显示的告诉 编译器;

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



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

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

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

相关文章
相关标签/搜索