c++导出与加载dll
思路:导出dll中类的智能指针的指针(extern "C"不允许导出C++独有的类型,如智能指针。但是可以导出智能指针的指针),然后使用该类的对象指针。
一、下面对dll程序使用抽象接口方式,以MyDll类为例,进行如下操作:
1、新建抽象接口类IMyDll
2、MyDll继承IMyDll
下面标黄的为改动的地方
MyDll.h
#pragma once #include "IMyDll.h" class MyDll:public IMyDll { public: MyDll(); ~MyDll(); void setNumber(int number); int getNumber() const; private: int m_number = 0; };
MyDll.cpp 无任何改动
#include "MyDll.h" MyDll::MyDll() { } MyDll::~MyDll() { } void MyDll::setNumber(int number) { m_number = number; } int MyDll::getNumber() const { return m_number; }
下面为新增的文件
IMyDll.h
/***************************************************************************************************** * C++抽象接口类: * 虚析构 * 纯虚函数 * 无成员变量 ****************************************************************************************************/ #pragma once class IMyDll { public: virtual ~IMyDll(){} virtual void setNumber(int number) = 0; virtual int getNumber() const = 0; };
IMyDll.cpp
#if defined(_MSC_VER_) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) #ifdef MYDLL_EXPORTS //注意格式 *_EXPORTS #define MYDLL_API __declspec(dllexport) #else #define MYDLL_API __declspec(dllimport) #endif #else #define MYDLL_API __attribute__((visibility("default"))) #endif #include "IMyDll.h" #include "MyDll.h" #include <memory> std::shared_ptr<IMyDll> sptr; extern "C" MYDLL_API std::shared_ptr<IMyDll>* GetObj() { sptr = std::make_shared<MyDll>(); return &sptr; //返回引用(地址),不能使用局部变量,否则出作用域后为空 }
VS运行,得到dll和lib。注意x64 Debug、x64 Release版本是不同的。
建议对Debug版本,VS设置如下:
我们开发时需要三个文件:IMyDll.h、MyDll.dll、MyDll.lib(调试时若无需进入dll程序内,lib可以不要)。相对路径是相对于main.cpp所在路径
发布时只需要:MyDll.dll。相对路径是相对于exe所在路径
二、使用dll
三个文件放到如下位置
main.cpp
#include "../include/Platform/Common.h" #include "../include/IMyDll.h" #include <iostream> #include <memory> int main() { void* pMyDll = LOAD_LIB("../include/MyDlld.dll"); //可以从ini中加载指定的dll if (pMyDll != nullptr) { using PF = std::shared_ptr<IMyDll>*(*)(); //函数指针类型别名 PF pf = (PF)FIND_FUNC(pMyDll,"GetObj"); //p指向dll中GetObj() std::shared_ptr<IMyDll> sptrMyDll = *pf(); //p是指针的指针,所以取值 //调用成员函数 sptrMyDll->setNumber(10); std::cout << sptrMyDll-> getNumber() << std::endl; } //注意释放(在合理的位置) CLOSE_LIB(pMyDll); pMyDll = nullptr; //非new,所以无需delete,只需置空 return 0; }
具体Gitee
c++ · xixixing/c++与qt导出与加载dll - 码云 - 开源中国 (gitee.com)
【参考】
SetDllDirectory不起作用(DllNotFoundException) - .net - 码客 (oomake.com)