您的位置:首页 > 其它

VC编写DLL

2009-06-29 10:00 127 查看
将类定义改为:class __declspec(dllexport) CInDLL 就可以了。(译者:你也许不相信会有这么简单,我也不相信。:-) 这样产生的工程在编译时是正确的但是在使用时会产生错误,因为你包含的头文件中也是使用__declspec(dllexport),而使用这个DLL的工程中并没有引出这个类,而是需要引入这个类)在使用时需要将类定义改为class __declspec(dllimport) CInDLL就可以了。

使用定义文件可以有效的避免这个问题,这种方法是利用宏定义在不同的地方产生不同的编译代码:在头文件中加入如下的代码:

#ifdef _CLASSINDLL
#define CLASSINDLL_CLASS_DECL _declspec(dllexport)
#else
#define CLASSINDLL_CLASS_DECL _declspec(dllimport)
#endif

#endif // ClassInDLL_H
//将class __declspec(dllexport) CInDLL改为
class CLASSINDLL_CLASS_DECL CInDLL
{
CInDLL();
...
}

在实现这个类的CPP文件的顶部加入#define _CLASSINDLL语句。
#define _CLASSINDLL
CInDLL::CInDLL()
{
}
...

这样一来在使用这个类时就可以不做任何改动了。

(译者:这中方法在没有使用MFC时可以使用,如果你使用MFC生成MFC DLL那么只要做如下定义就可以了

class AFX_EXT_CLASS yourClass)

extern "c" 和 .def 文件的作用 2009-02-18 16:33

首先,我们需要知道C和C++编译器对函数名字的处理方式是不一样的;其次,就是同为C编译器的两个不同产品,在编译时对函数名字的处理方式也是有区别的,比如microsoft vc++与dev c++。所以,extern "C"与.def文件正是为了解决这两种情况而引入的处理方法。

第一、extern "C"的作用
比如一个C源程序A.c要使用C++编写的库函数,在A.c中#include "B.h",其中B.h中有要使用的函数的原形声明func。当编译链接源程序时,却发现了“链接错误,未决的外部符号...”的错误,这是什么原因呢?
原因就是,C编译器编译A.c时,将func编译为func,当链接时链接器去C++库中寻找func,但是C++的编译器在编译库时将func编译成_func@yyy@rrr,自然链接器就找不着相应的函数的信息了,所以就会报错!有什么办法可以处理这种情况呢?——可以在编写C++库的时候,为每一个函数(或导出函数)加上extern "C",它的含义是告知C++编译器在编译这些函数的时候,以C编译器的方式处理函数名。这样生成的库中的函数名字就是func了,当C程序调用库函数,编译链接时,链接器就能找到期望的信息,则链接成功。

第二、.def文件的作用(仅与VC++编程相关)
前面提到,不同厂商开发的两个C编译器也会有一些差异,最突出的就是microsoft的C编译器,它对函数名字的处理很特别(究竟是什么样子,可以使用Dumpbin工具查看dll的导出函数),所以要在使用他方编写的库时,程序链接能成功,有两种方法:1使用库编写者使用的C编译器(这里指VC++),显然这种方法不合理;2库的编写者在使用VC++编写库时使用.def文件。
.def文件的作用即是,告知编译器不要以microsoft编译器的方式处理函数名,而以指定的某方式编译导出函数(比如有函数func,让编译器处理后函数名仍为func)。这样,就可以避免由于microsoft VC++编译器的独特处理方式而引起的链接错误。

用.def文件描述dll的输出函数,比如
EXPORTS
DllFun1 @1 NONAME
DllFun2 @2 NONAME
DllFun3 @3 NONAME
DllFun4 @4 NONAME
...
@后面是dll输出函数的顺序号,顺序号要求在1到max(函数个数)之间。
用.def声明了输出函数以后,不要在头文件里再声明AFX_EXT_API或者是dllexport之类的声明。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: