使用接口从动态链接库(DLL)导出类

3

IClass (My interface):

#ifndef _ICLASS_H
#define _ICLASS_H

#include <sstream>

namespace Test
{
    class __declspec(dllexport) IClass
    {
    public:     
        virtual ~IClass() {}                

        virtual bool Init(const std::string &path) = 0;     
    };
}

#endif

Class.h

#ifndef _CLASS_H
#define _CLASS_H

#include "IClass.h"
#include <memory>
#include <sstream>
#include <stdio.h>

namespace Test
{
    class Class: public IClass
    {
    public:
        Class();
        ~Class();               

        bool Init(const std::string &path);         
    };
}

#endif

Class.cpp

#include "Class.h"

namespace Test
{
    Class::Class()
    {       
    }

    bool Class::Init(const std::string &path)
    {
        try
        {
            // do stuff

            return true;
        }
        catch(std::exception &exp)
        {
            return false;
        }
    }   
}

主函数(在exe和dll中默认链接)

#include "IClass.h"

using namespace Test;

int main(int argc, char* argv[])
{
    std::shared_ptr<IClass> test = std::make_shared<Class>(); // error: unreferenced Class

    test->Init(std::string("C:\\Temp"));
}

目前没有声明类

-> 如果我在主函数中包含Class.h,会出现以下错误:LNK2019:未解析的外部符号,为了解决这个链接问题,可以添加class __declspec(dllexport) Class : public IClass,但这样做是否可行?

-> 我也不能这样做:std::shared_ptr<IClass> test = std::make_shared<IClass>(); (因为不允许创建抽象类对象)

如何解决这个问题,这是最佳实践吗?


1
可能是如何从dll中导出C++类?的重复问题。 - Iłya Bursov
如果您导出(和导入)类并包含相关的头文件,则程序将编译并运行。无法确定这是否是良好的实践,因为您没有说明您的目标或约束条件。 - David Heffernan
@DavidHeffernan:请查看我帖子的编辑。 - leon22
我仍然不知道你的目标或限制。 - David Heffernan
@leon22 我们必须知道你是否想要将“Class”的实现细节对其用户进行掩盖。如果是的话,请看我的回答:使用工厂函数。如果不是,直接导出 Class 也可以。 - manuell
@manuell 我想要对它进行掩码处理。谢谢你,manuell。 - leon22
1个回答

2
如果您想让您的EXE分配一个新的“Class”对象,则EXE代码必须知道Class类型。如果您想要向EXE保持Class类型未知,则一种解决方案可能是从您的DLL中导出一个工厂函数,该函数将构造一个Class对象并将其作为IClass指针返回。
请参见如何正确实现C++中的工厂模式

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接