extern "C" _declspec (dllexport)和_declspec (dllexport)的分别,看看我理解对不对?

samgamlung 2007-03-25 04:11:28
我发现在如果DLL里边的函数用extern "C" _declspec (dllexport)使用函数,就可以用LoadLibrary来使用DLL。

而用_declspec (dllexport)的时候,只有隐式调用。显式调用错误。对不对?

像下列的,我用显试调用的时候不能调用。然后用查看工具看DLL里边的函数是乱码。如果显式调用SQU这个函数的话,调用不了,错误。如用extern "C" _declspec int SQU(int) 方式,就可以显式设用,这究竟是什么问题,很不方便。有什么方法,显式、隐式都能用呢?

#ifdef C_CPP_DLL
#define MYDLL extern "C" _declspec (dllexport)
#else
#define MYDLL _declspec(dllexport)
#endif
MYDLL int SQU(int);
...全文
4760 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
x396448534 2010-10-24
  • 打赏
  • 举报
回复
extern "C" 是解决编译器乱改名
xengine-qyt 2010-10-21
  • 打赏
  • 举报
回复
你那种方法显示和隐式都可以调用的话 要加上DEF 文件即可。 然后 定义下导出函数

extern "C " _declspec (dllexport) void __stdcall

由于压栈方式不同,在C++调用的时候 显示调用的时候 函数要加上 __stdcall。
gf_zh 2010-10-21
  • 打赏
  • 举报
回复
明白点了。学习
eoenetcom 2010-07-09
  • 打赏
  • 举报
回复
楼上的兄弟都对
加extern "C "是为了说明使用的C风格的命名方式
C和C++导出的函数在链接库里面的名字是不同(在C++中不同的编译器都有所不同)
你使用查看导出函数,C++ 和C的命名风格是不同的
C++支持重载,所以编译生成的函数名不同的

还有一点
这个很常识的问题
LZ要牢记
Kevin_Perkins 2010-07-09
  • 打赏
  • 举报
回复
LZ查一下到处函数表就明白为什么了,注意函数名字。
名字改编和extern “C””
C++编译器在生成DLL时,会对导出的函数进行名字改编,并且不同的编译器使用的改变规则不一样,因此改编后的名字会不一样。这样,如果利用不同的编译器分别生成DLL和访问该DLL的客户端代码程序的话,后者在访问该DLL的导出函数时会出现问题。为了实现通用性,需要加上限定符:extern “C”。
但是利用限定符extern “C”可以解决C++和C之间相互调用时函数命名的问题,但是这种方法有一个缺陷,就是不能用于导出一个类的成员函数,只能用于导出全局函数。
LoadLibrary导入的函数名,对于非改编的函数,可以写函数名;对于改编的函数,就必须吧@和号码都写上,一样可以加载成功,可以试试看。
fengyun1974_lzz 2010-07-09
  • 打赏
  • 举报
回复
加extern "C "该dll输出的函数名就是自己定义的函数,不需要Def文件
没有extern "C " 输出的函数名不确定,取决于编译器.
renxu350 2010-07-08
  • 打赏
  • 举报
回复
加入如下代码:


#ifdef __cplusplus
#define EXPORT extern "C" __declspec(dllexport)
#else
#define EXPORT __declspec(dllexport)
#endif


然后函数实现这样写:


EXPORT void SomeFunction( void )
{
.....
}

moorguide 2010-07-08
  • 打赏
  • 举报
回复
大智慧
kissstefani 2010-07-07
  • 打赏
  • 举报
回复
学习了。。。
mengwuji 2010-07-07
  • 打赏
  • 举报
回复 1
哎!!回答的一团糟,我来解释下吧!
加一个 extern "C"的用处就是:因为编译器害怕你写的函数与本有的函数重名,所以在产生连接时‘可能’会加一点儿东西,会把原来的的函数名称改变,当你应用程序调用函数时,以前的那个函数名称已经改变,所以自然调用不到,因此会出错!!!!加一个 extern "C" 就是解决编译器乱改名称的问题!!!
明白了吧! 给我分呀!
kissstefani 2010-07-07
  • 打赏
  • 举报
回复
tiantangxingkong 2009-10-14
  • 打赏
  • 举报
回复
楼主搜一下函数的调用约定就应该明白什么意思了
windows_star 2009-10-14
  • 打赏
  • 举报
回复
由于C++里面有函数重载,所以在编译的时候,编译器会在你写的,也就是你希望导出的函数
后面加上一些关于参数的信息,也就是真正导出的函数名字和你想要的不一样。
又由于C语言没有函数重载,所以用EXTERN "C"的意思就是告诉编译器不要按照C++那样修改函数
名称。

不知道你明白没。

建议你用模块定义文件 .def文件来写DLL,这样可以保证导出函数的纯净。
aidy22 2009-10-14
  • 打赏
  • 举报
回复
学习
DaYuTou 2007-05-30
  • 打赏
  • 举报
回复
__declspec (dllexport)输出函数的时候,用loadlibrary又有何不可?
关键是你要知道输出符号的名字。
因为c++中有函数重载,通过函数名并不能唯一确定一个函数,所以使用c++方式编译函数时系统会在目标码中的内部修饰符中加入参数信息和返回值信息等,这时候你能估算出正确的名称吗?
如果加了extern "C"则是用c的方式编译,函数在目标码中的内部修饰符就是_函数名,只要用函数名就可以调用
ReverseEngineering 2007-05-26
  • 打赏
  • 举报
回复
extern "C"避免C++编译器在名字前面加东西。
gxpotato 2007-03-26
  • 打赏
  • 举报
回复
你用DUMPBIN查看有无extern "C"的DLL就会明白了。
gxpotato 2007-03-26
  • 打赏
  • 举报
回复
extern "C"只是表示这个可以被C语言调用,除了这个之外,没有什么更多含义。

因为C语言的编译器和C++的不同,C++的会有个叫做函数名打散的机制,比如函数:int add(int a,int b)在C++里面编译之后,就不是int add(int a,int b),而是类似:int add@WEROIUERH(int a,int b)的函数名,而且是随机的,如果不用extern "C",C语言根本没法调用,而在C++里面可以通过@的顺序来调用。

这个是个比较基本的知识点。。
kimryo 2007-03-26
  • 打赏
  • 举报
回复
区别是到处的名字有无应用name mangling...
plphoenix 2007-03-26
  • 打赏
  • 举报
回复
这个是编译器对C++和C的区别,编译器在编译C++的程序的时候会把函数编译成函数名+'_'+参数...的形式,比如int f(int a)就是 _f_int这个样子(根据编译器不同可能编译成不一样的方式),所以这个也解释了为什么C++如何支持重载的,而C编译器只能编译成_f这个样子,extern "C"表示按照C来编译,现在知道为什么了吧
加载更多回复(6)

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧