DLL(一)
#define DLL_API _declspec(dllexport)
int DLL_API/*_stdcall*/ add(int a,int b)
{
return a+b;
}
int DLL_API/* _stdcall*/ subtract(int a,int b) //注意这里就算注释掉stacall还是会发生名字改编
{ //注释掉之后虽然会使用默认的_cdecall调用约定但是由于没有
return a-b; //加上extern"C",还是会用C++的编译器从而发生名字改编
}
extern"C" int DLL_API /*_stdcall*/ add(int a,int b)
{
return a+b;
}
int DLL_API /*_stdcall */ subtract(int a,int b)
{
return a-b;
}
我们发现在用VS2005编译全局函数add时,由于使用了extern"C",所以用c的方式进行编译从而也就没有发生通常的名字改编,而subtract则改变了
名字改编有一个问题就是如果用C语言编写的客户端程序来调用subtract的话则会找不到,因为C++的编译器实际上把subtract进行了名字改编。如果是用C++编译器来编写客户端代码则可以进行访问。
extern"C" int DLL_API _stdcall add(int a,int b)
{
return a+b;
}
extern"C" int DLL_API _stdcall subtract(int a,int b)
{
return a-b;
}
从而我们发现即使声明了extern"C",但是如果不是使用默认的_cdecall而是使用如_stdcall调用约定还是会发生名字改编。
DLL中导出函数的声明有两种方式:一种为在函数声明中加上__declspec(dllexport),这里不再举例说明;另外一种方式是采用模块定义(.def) 文件声明,用def的方式不会发生名字改编的事情。
一开始按照孙鑫视频中的方法进行操作,但是用dumpbin怎么也看不到导出函数的身影,而用__declspec(dllexport)就可以,但是明明说是用def也可以的啊。
在网上找了一下也没有发现我想要的,后来发现在VS2005上要把.def文件在对话框中加上,就行一些.lib文件一样。就像下面这样
是
我的.def文件是下面这样定义的:
;作者:---
LIBRARY yoyo
EXPORTS
add @ 1
subtract @ 2
yoyo.cpp文件就是下面这样简单,没有一些复杂的宏了
{
return a+b;
}
int subtract(int a,int b)
{
return a-b;
}
之后就一切OK了,我们发现名字没有被C++编译器改编,这样我们就可以以后放心的使用了。