导出函数__declspec(dllexport)

来源:互联网 发布:手机怎么进淘宝试衣间 编辑:程序博客网 时间:2024/05/01 05:15

 关于DLL的函数:

动态链接库中定义有两种函数:导出函数(export   function)和内部函数(internal   function)。
导出函数可以被其它模块调用,内部函数在定义它们的DLL程序内部使用。

输出函数的方法有以下几种:

1、传统的方法

在模块定义文件的EXPORT部分指定要输入的函数或者变量。语法格式如下:
entryname[=internalname]   [@ordinal[NONAME]]   [DATA]   [PRIVATE]

其中:

entryname是输出的函数或者数据被引用的名称;

internalname同entryname;

@ordinal表示在输出表中的顺序号(index);

NONAME仅仅在按顺序号输出时被使用(不使用entryname);

DATA表示输出的是数据项,使用DLL输出数据的程序必须声明该数据项为_declspec(dllimport)。

上述各项中,只有entryname项是必须的,其他可以省略。

对于“C”函数来说,entryname可以等同于函数名;但是对“C++”函数(成员函数、非成员函数) 来说,entryname是修饰名。可以从.map映像文件中得到要输出函数的修饰

名,或者使用 DUMPBIN   /SYMBOLS得到,然后把它们写在.def文件的输出模块。DUMPBIN是VC提供的一个工具。

如果要输出一个“C++”类,则把要输出的数据和成员的修饰名都写入.def模块定义文件。

2、在命令行输出

对链接程序LINK指定/EXPORT命令行参数,输出有关函数。

3、使用MFC提供的修饰符号_declspec(dllexport)

在要输出的函数、类、数据的声明前加上_declspec(dllexport)的修饰符,表示输出。__declspec (dllexport)在C调用约定、C编译情况下可以去掉输出函数名的下划线前缀。

extern   "C "使得在C++中 使用C编译方式成为可能。在“C++”下定义“C”函数,需要加extern   “C”关键词。用extern   "C "来 指明该函数使用C编译方式。输出的“C”函数可

以从“C”代码里调用。

例如,BaseFunce 工程中 的一个C++文件有如下类:

#ifdef  _BASEFUNC_EXPORT_
#define  BASE_API   __declspec(dllexport)
#else
#define  BASE_API   __declspec(dllimport)
#endif

class BASE_API CJCJMsgCmd_PrintRoadMap : public CJCJMsgCmd 
{
public:

 CJCJMsgCmd_PrintRoadMap();

 virtual ~CJCJMsgCmd_PrintRoadMap();

 virtual void Execute();

}

在另外工程中 CDlgJCJModule类中 需要将 CJCJMsgCmd_PrintRoadMap类中的 函数链接到 CDlgJCJModule 的C++ 可执行文件中,在CDlgJCJModule的CPP文件头部加上“#include "..\BaseFunc\JCJMsgCmd_QueryXQ.h"”

导出 C 函数以用于 C 或 C++ 语言可执行文件

如果在用 C 编写的 DLL 中有希望从 C 语言或 C++ 语言模块访问的函数,则应使用 __cplusplus 预处理器宏确定正在编译的语言,然后,如果是从 C++ 语言模块使用,则用 C 链接声明这些函数。如果使用此技术并为 DLL 提供头文件,则这些函数可以原封不动地由 C 和 C++ 用户使用。

可由 C 和 C++ 客户端应用程序使用的头文件:

 
// MyCFuncs.h#ifdef __cplusplusextern "C" {  // only need to export C interface if              // used by C++ source code#endif__declspec( dllimport ) void MyCFunc();__declspec( dllimport ) void AnotherCFunc();#ifdef __cplusplus}#endif

如果需要将 C 函数链接到 C++ 可执行文件,并且函数声明头文件没有使用上面的技术,则在 C++ 源文件中添加下列内容以防止编译器修饰 C 函数名:

 
extern "C" {#include "MyCHeader.h"}

 

导出 C++ 函数以用于 C 语言可执行文件

如果在用 C++ 编写的 DLL 中有希望从 C 语言模块访问的函数,应使用 C 链接而不是 C++ 链接来声明这些函数。除非另外指定,C++ 编译器使用 C++ 类型安全命名约定(也称作名称修饰)和 C++ 调用约定(使用此调用约定从 C 调用会很困难)。

若要指定 C 链接,请为函数声明指定 extern "C"。例如: 

extern "C" __declspec( dllexport ) int MyFunc(long parm1);