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)

【参考】

Dll导出C++类的3种方式_c++ 导出类-CSDN博客

SetDllDirectory不起作用(DllNotFoundException) - .net - 码客 (oomake.com)

DLL相关问题_caz28的博客-CSDN博客

C++经典问题_09 函数指针_函数指针 using_Fioman_Hammer的博客-CSDN博客

在DLL中获取智能指针的方法_c链接函数无法返回c++类-CSDN博客

posted @ 2023-11-26 20:44  夕西行  阅读(343)  评论(0编辑  收藏  举报