问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何封装c++程序成dll文件

发布网友 发布时间:2022-05-04 18:38

我来回答

1个回答

热心网友 时间:2022-06-25 01:39

C++编写DLL的方法

在写C++程序时,时常需要将一个class写成DLL,供客户端程序调用。这样的DLL可以导出整个class,也可以导出这个class的某个方法。

一、导出整个class

方法很简单,只需要在类的头文件中class和类名之间加上_declspec(dllexport),同时在另外一份提供给客户端调用程序使用的类的头文件中class和类名之间加上_declspec(dllimport)。为了能让客户端程序和DLL程序公用该类的一份头文件,通常在类的头文件中使用宏和预编译指令来处理。如下DLLTest.h:

#ifdef DLL_TEST_API

#else

#define
DLL_TEST_API _declspec(dllimport)
#endif

Class DLL_TEST_API CDLLTest
{

Public:
CDLLTest();

~CDLLTest();

int Add(
int
a, int
b);

};
DLLTest.cpp如下:

#define
DLL_TEST_API _declspec(dllexport)

#include “DLLTest.h”

………………………………………
这样,在DLL编译时DLL_TEST_API被定义为_declspec(dllexport),而且客户端程序编译时它被定义为_declspec(dllimport)。

二、导出这个类的某个或者某几个方法。

这时,需要将_declspec(dllexport)放到成员函数名前,如DLLTest.h:

#ifdef DLL_TEST_API

#else

#define
DLL_TEST_API _declspec(dllimport)
#endif

Class CDLLTest
{

Public:
CDLLTest();
    
~CDLLTest();
int DLL_TEST_API Add(
int
a, int
b);

};

但是,如果仅仅是这样的话,当客户端程序#include这个头文件后,定义DLLTest这个类的一个对象后(静态方式链接DLL),客户端程序无法链接通过,会提示构造函数和析构函数无法解析,此时,需要将构造函数和析构函数前也加上DLL_TEST_API宏即可。

当然这里还有个问题就是类的函数在导出后,名字会发生变化,我们可以在函数名前再加上extern “C” ,如 extern “C” DLL_TEST_API int Add(int a ,int b);但这只解决了C与C++调用时名字变更问题,可靠的方法还是增加一个模块定义文件def,在该文件中定义导出函数的名称,我们将在后面看到样例。

DLL编写完成后,就只剩下客户端程序如何去调用该DLL了,静态方式调用DLL和动态方式调用DLL。

一、静态方式调用DLL

这个方法就简单了,将DLLTest.h头文件和DLLTest.lib,DLLTest.dll文件拷贝到客户端程序的当前目录下,在客户端程序中#include<DLLTest.h>,然后通过#pragma comment(lib,”DLLTest.lib”)的方式引入lib库,或者在客户端程序的工程属性里面增加对该lib文件的引入。

然后就可以在客户端程序中如同使用本地的一个class一样使用该DLL了,如:

CDLLTest dllTest;

dllTest.Add(
1
,2
);

二、动态方式调用DLL

动态调用这个DLL,就需要对这个class进行修改了。

首先,在DLLTest.cpp文件中增加一个全局函数,该函数可以返回这个class的一个实例,这样,客户端程序调用这个全局函数后,得到该class的实例,就可以调用该class的实例方法了。

extern
“C” _declspec(dllexport) CDLLTest* GetInstance()
{

return
new
CDLLTest;
}
注:extern “C” 只是解决了c与c++编译器之间的兼容问题,如果需要和其他编译器之间兼容,可靠的办法还是增加一个.def文件,文件内容如下:

LIBRARY “DLLTest”

EXPORTS

GetInstance
= GetInstance
这样就指定了DLL的函数导出后的名称仍然不变。

这样,客户端程序就可以通过该函数来获取class的一个实例了。如下:

先需要定义一个函数指针类型:

typedef CDllTestBase* (*pfGetInst)();

//
注:CDllTestBase类后面会介绍。

HMOUDLE hMod
= LoadLibrary( _T(“DLLTest.DLL”) );

if(hMod)
{
pfGetInst pfGetInstance
= (pfGetInst)GetProcAddress(“GetInstance”);
if( p )
{

//
通过基类指针指向派生类对象

CDllTestBase * pInst = pfGetInstance ();
if( NULL
!= pInst )
{
pInst
->Add( 1
,2
);
}

   if( NULL
!= pInst )
{

//
释放对象

delete pInst;
}
}
}
当然,这里还是需要include这个DLL的头文件DLLTestBase.h,如果将之前所写的头文件DLLTest.h直接拷贝到客户端程序的当前目录下,并include进来的话,在编译连接时,是无法通过的,我们需要对这个头文件进行修改,首先增加一个.h 文件DLLTestBase.h,在这个文件中我们将需要在客户端程序中调用的函数都命名成纯虚函数,然后让CDLLTest类继承自CDLLTestBase类,DLLTestBase.h如下:

Class CDLLTestBase
{
Public:
Virtual
~CDLLTestBase(){};//
虚析构函数,且为内联函数

Virtual int
Add(int
a, int
b) = 0
;

}
DLLTest.h修改后如下:

#include “DLLTestBase.h”
Class CDLLTest :
public
CDLLTestBase
{
Public:
CDLLTest();

~CDLLTest();

int
Add(int
a, int
b);
};
注:这里的DLLTestBase需要提供一个虚析构函数,这样在客户端程序中就可以通过基类指针来释放派生类对象了。

这样,只需要将DLLTestBase.h拷贝到客户端程序的当前目录下,然后在客户端程序中#include”DLLTestBase.h”,就可以如上面介绍一样在客户端程序中调用DLL里面的方法了。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
特别精辟的个性签名(非常经典的个性句子) 特别经典的个性签名(非常惊艳的个性句子) 文艺范十足的个性签名(温柔治愈的个性签名句子) wps文字怎么设置每页头和尾 27岁的女人需要补充哪些营养元素 27岁该重视美容了吗?都可以用哪些方法好些呢? airpods连不上手机怎么回事 - 知百科 腰肌劳损能养好吗? 有一段相声讲的是原始人打猎,唱歌,学说话的,请问名字是什么? 个人征信逾期记录的修复攻略,手把手传授 java 程序调用c的dll怎么配置文件 C# 调用 C写的DLL 问题 c语言调用dll里的命令并输出 c语言dll,怎样常驻内存(或许是多线程) 【求助】如何把C编译成dll? 哪些dll文件和c中的库函数有什么区别? 用c语言,纯c做一个dll,里面有两个函数,这两个函数之间能相互调用么 dll文件如何用C语言生成 用C调用DLL中的函数 用VB调用c dll , 函数指针如何处理? C+的dll如何用易语言正确调用? 在C语言中,能简单介绍一下DLL是干什么的么? c怎么生成dll文件? 用C语言编写DLL 在EXCEL表格里面,如何将一列数字的前面几位数替换掉? 关于excel的问题:如何把一整排数字一次性修改呢!悬赏100分,满意再追加1倍.急!! 在excel中我需要替换一列数字,怎么替换? EXCEL怎么把一列的数据替换到另一列数据里面覆盖掉,空格不替换? 学校是自动获取ip的,请问如何查询获取的iP记录?win7系统的。。。 win7系统下如何查看当前的ip地址,用的无线路由器,已经自动获取的那种 c#调用c生成的DLL,得到其结构体的数据 金牛座的幸运石 炸鸡锁骨加什么香料好吃? 什么没有雷州升级 有没有用蚌壳做的珍珠项链 这款10mm淡紫色珍珠项链值多少钱 珍珠项链有保健作用吗 珍珠项链会越戴越亮么? 一条珍珠项链的价值? 珍珠项链怎么辨别真假? 有什么好玩的2D横版网络游戏(除DNF.鬼吹灯) 现在大陆有什么好玩的横版2d网游啊? 蜂蜜装在矿泉水瓶里 凝固了怎么办 才能变成液体 蜂蜜怎么变软? 寻找一款儿时的精彩2D横版过关射击游戏 吃宝石的2D横版闯关游戏叫什么 蜂蜜变硬怎么办 悦活蜂蜜变得坚硬无比!!谁知道怎么办? 有什么类似冒险岛的2D横版游戏QQ三国除外 怎样取消华为手机v30最左侧屏幕?