您当前的位置: 首页 >  c++

插件开发

暂无认证

  • 1浏览

    0关注

    492博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

C++-导出类-导出宏-纯虚函数-DllMain函数-调用约定与参数命名

插件开发 发布时间:2022-05-26 08:29:04 ,浏览量:1

文章目录
    • 1.普通类导出
    • 2.接口类导出
    • 3.调用约定与参数命名
    • 4.名字修饰约定
    • 5.MFC导出宏
    • 6.DLLMain函数
    • 7.一个DLL在内存中只有一个实例
   在编写应用软件时,代码重用是非常关键的一步,C++编程语言里,为了使编写的dll文件,能够实现重用,必须采取一些规则,否则不同编译器生成的dll,不用重用。首先在dll里编写的类必须导出。如下所示:

1.普通类导出

   头文件:DLL_TEST_Export.H

#ifndef _DLL_TEST_H
#define _DLL_TEST_H

// 通过宏来控制是导入还是导出
#ifdef _DLL_TEST
#define DLL_TEST_API __declspec(dllexport)
#else
#define DLL_TEST_API __declspec(dllimport)
#endif

// 导出/导入变量声明
class DLL_TEST_API DLLClass
{
public:
	void Show();
};


DLL_TEST_API float _stdcall Test(int i,bool j);


#endif

   实现文件:DLL_TEST_Export.cpp

#include "stdafx.h"
#define _DLL_TEST
#include "DLL_TEST_Export.h"

#include "stdio.h"

//APIENTRY声明DLL函数入口点
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	switch (ul_reason_for_call)

	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;

	}
	return TRUE;
}

void DLLClass::Show()
{
	printf("DLLClass show!");
}

DLL_TEST_API float _stdcall Test(int i, bool j)
{
	return 1.0;
}

   调用文件:

#include "DLL_TEST_Export.h"
#pragma comment(lib,"DLLTest.lib")
int main(int argc, char *argv[])
{
 DLLClass dc;
  dc.Show();
 return 0;
}

   通过Dependency Walker可以看到,这时候的dll导出的是跟类相关的函数:如构造函数、赋值操作符、析构函数、其它函数,这些都是使用者可能会用到的函数。如下图所示: 在这里插入图片描述    这种简单导出类的方式,除了导出的东西太多、使用者对类的实现依赖太多以外,还有其他问题:必须保证使用同一种编译器。导出类的本质是导出类里的函数,因为语法上直接导出了类,没有对函数的调用方式、重命名进行设置,导致了产生的dll并不通用。

2.接口类导出

   定义一个抽象类(都是纯虚函数),调用者跟dll共用一个抽象类的头文件,dll中实现此抽象类的派生类,dll最少只需要提供一个用于获取抽象类对象指针的接口。 这种方式利用了C++类的虚函数,类似COM思想,采用接口跟实现分离,可以使得工程的结构更清晰,使用者只需要知道接口,而无需知道具体实现,产生的DLL通用没有特定环境限制。调用者跟DLL共用一个抽象类的头文件,调用者依赖于DLL的东西很少,只需要知道抽象类的接口,以及获取对象指针的导出函数,对象内存空间的申请和释放都在DLL模块中完成。    func.h文件(接口文件):

#pragma once
 
#ifdef _DLL_EXPORTS
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif
 
class IAnimal
{
public:
	virtual void eat() = 0;
	virtual void sleep() = 0;
	virtual void delObj() = 0;
};
 
extern "C" DLL_API IAnimal *GetCat();

   func.cpp文件:


// DynamicLib.cpp: 定义 DLL 应用程序的导出函数。
//
 
#include "stdafx.h"
 
#define _DLL_EXPORTS
#include "func.h"
 
#include 
using namespace std;
 
class Cat :public IAnimal
{
public:
	Cat()
	{
		cout             
关注
打赏
1665481431
查看更多评论
0.0429s