爱新觉罗二狗 2024-12-05 11:42 采纳率: 40%
浏览 10

c++ 动态链接库接口类动态链接库开发及使用

c++ 动态链接库接口类动态链接库开发及使用
我创建了一个接口类生成动态链接库,然后静态调用,使用的是lib
实现方法是:
先创建了一个接口类(纯虚类)

//Interface.h
class __declspec(dllexport) Interface
{
  virtual void SetParam( const short a, const short b, const short c ) = 0;
protected:
    short aa;
    short bb;
    short cc;
}
DLLIMPORT Interface* MakeClassPtr();

然后创建了一个继承到接口类的来实现其功能

//InterfaceReal.h
#include "Interface.h"
class  InterfaceReal:public Interface
{
public:
    void SetParam( const short a, const short b, const short c) override;
}
//InterfaceReal.cpp
void InterfaceReal::SetParam( const short a, const short b, const short b )
{
    aa= a;
    bb= b;
    cc = c;
}
extern "C" __declspec(dllexport) Interface* MakeClassPtr()
{
    return new InterfaceReal();
}

生成lib和dll

使用是将lib和dll加到test工程中,然后将Interface.h也加入Test工程中,使用下面代码

Interface *xx= MakeClassPtr();
xx->SetParam(1,1,15);

但是实际上1,1,15并没有赋值给aa bb cc

  • 写回答

1条回答 默认 最新

  • 越重天 新星创作者: Java技术领域 2024-12-05 19:48
    关注

    本答案参考 多次询问 ChatGPT-3.5 后选择的最佳回答,若是满意,还请采纳,谢谢

    1. 问题分析
      • 在提供的代码中,InterfaceReal::SetParam函数的参数列表存在错误。函数定义中的参数const short b被重复定义了,应该是const short c。这可能导致未定义行为,从而使得值没有正确赋给成员变量。
    2. 修正后的代码实现
      • Interface.h
    class __declspec(dllexport) Interface
    {
    public:
        virtual void SetParam(const short a, const short b, const short c)=0;
    protected:
        short aa;
        short bb;
        short cc;
    };
    // 注意这里的函数声明,用于创建接口类的实例指针
    extern "C" __declspec(dllexport) Interface* MakeClassPtr();
    
    • InterfaceReal.h
    #include "Interface.h"
    class InterfaceReal : public Interface
    {
    public:
        void SetParam(const short a, const short b, const short c) override;
    };
    
    • InterfaceReal.cpp
    #include "InterfaceReal.h"
    
    // 修正后的SetParam函数实现
    void InterfaceReal::SetParam(const short a, const short b, const short c)
    {
        aa = a;
        bb = b;
        cc = c;
    }
    
    // 创建接口类实例的函数实现
    extern "C" __declspec(dllexport) Interface* MakeClassPtr()
    {
        return new InterfaceReal();
    }
    
    • test.cpp(使用动态链接库的代码示例)
    #include <iostream>
    #include "Interface.h"
    
    int main()
    {
        Interface* xx = MakeClassPtr();
        if (xx)
        {
            xx->SetParam(1, 1, 15);
            // 这里可以添加代码来验证成员变量是否被正确赋值,例如输出成员变量的值
            // std::cout << static_cast<InterfaceReal*>(xx)->aa << " " << static_cast<InterfaceReal*>(xx)->bb << " " << static_cast<InterfaceReal*>(xx)->cc << std::endl;
            delete xx;
        }
        return 0;
    }
    
    1. 关于动态链接库开发与使用的更多说明
      • 动态链接库(DLL)开发的一般步骤
        • 定义接口类
          • 接口类通常是纯虚类,它定义了一组抽象的函数,这些函数将由具体的实现类来实现。例如在上述代码中,Interface类就是接口类,SetParam函数是一个抽象函数。
          • 接口类的设计应该遵循单一职责原则,每个函数应该有明确的功能。
        • 实现具体类
          • 具体类继承自接口类并实现接口类中的抽象函数。如InterfaceReal类继承Interface类并实现了SetParam函数。
          • 在实现函数时,要确保函数的逻辑正确,并且遵循接口类定义的函数签名。
        • 导出函数
          • 在Windows平台下,使用__declspec(dllexport)来标记要导出的函数和类。在上述代码中,Interface类和MakeClassPtr函数都被标记为导出。
          • 对于跨平台的动态链接库开发,可能需要使用更通用的构建系统(如CMake)来管理编译和链接过程。
      • 动态链接库的使用步骤
        • 链接库文件
          • 在使用动态链接库的工程中,需要将生成的.lib(导入库)和.dll文件添加到工程中。在Visual Studio中,可以通过项目属性设置来添加库文件的路径和名称。
          • 如果是在命令行编译,需要使用相应的编译选项(如-l选项来指定库名)来链接库文件。
        • 包含头文件
          • 将定义接口类的头文件(如Interface.h)包含到使用动态链接库的源文件中。这样才能使用接口类的定义来创建对象和调用函数。
        • 调用函数
          • 通过调用导出的函数(如MakeClassPtr)来获取接口类的实例指针,然后使用该指针调用接口类中的函数(如SetParam)。
          • 在使用完动态链接库中的对象后,要记得释放资源,如使用delete操作符来释放通过new创建的对象。
    评论

报告相同问题?

问题事件

  • 创建了问题 12月5日