闪亮的马路 发表于 2024-10-10 09:30:32

c++函数指针与回调函数、动态库的问题

问题:
        现在是想实现这样一个问题。要做一个动态链接库,由于某些原因class B不想作为头文件对外,因为calss B中可能包含了其他文件导致作为动态链接库编译不过;
所以,现在做了一个接口文件class A,把A中的h文件作为动态链接库的头文件;

现在要实现这样一个事情,就是class B中有一个回调函数 CallbackB 需要回调class A中的CallbackA,然后把class B中的一些数据传过去;
然后对于链接该库的一方,会重写class A中的CallbackA,实现回调;

各位大神,请问这样怎么实现ClassA 跟B呢?

FishC 发表于 2024-10-10 09:30:48

要实现 Class A 和 Class B 之间的回调关系以及动态库的封装,主要的思路是利用函数指针或接口来解耦,实现数据传递与回调。以下是一个简单的实现示例说明如何实现这个功能。

1. **定义接口(Class A)**:

// Class A - 作为接口
class A {
public:
    // 这个回调函数将会被实现方重写
    virtual void CallbackA(int data) = 0;
    virtual ~A() {}
};

// 提供一个函数指针类型,指向 CallbackA
typedef void(*CallbackType)(int);

2. **实现内部逻辑(Class B)**:

// Class B - 实现库的内部逻辑
class B {
private:
    CallbackType m_callback;
   
public:
    B() : m_callback(nullptr) {}

    // 用于设置回调函数
    void SetCallback(CallbackType callback) {
      m_callback = callback;
    }

    // 模拟一些操作,然后通过回调返回信息
    void DoSomething() {
      int data = 42; // 例如,一些操作产生的数据

      // 调用回调函数
      if (m_callback) {
            m_callback(data);
      }
    }
};

3. **导出动态库接口**:

为 Class A 提供一个头文件即可,B 类和实现细节隐藏在动态库中。

// 动态库接口,供用户实现并导出
extern "C" {
    B* CreateBInstance() {
      return new B();
    }
   
    void DestroyBInstance(B* b) {
      delete b;
    }

    void BSetCallback(B* b, CallbackType callback) {
      if (b) {
            b->SetCallback(callback);
      }
    }
   
    void BDoSomething(B* b) {
      if (b) {
            b->DoSomething();
      }
    }
}

4. **客户端定义实现类并使用库**:

客户端重写 `CallbackA` 并通过函数指针实现回调。

#include "A.h"// 假设这里存放的是 A 类及 CreateBInstance 的头文件

class MyA : public A {
public:
    void CallbackA(int data) override {
      std::cout << "Callback received data: " << data << std::endl;
    }
};

// 实现回调函数
void MyCallback(int data) {
    std::cout << "Received data: " << data << std::endl;
}

int main() {
    B* bInstance = CreateBInstance();
    if (bInstance) {
      BSetCallback(bInstance, MyCallback);
      BDoSomething(bInstance);
      DestroyBInstance(bInstance);
    }
    return 0;
}

通过这种方式,Class A 作为接口暴露给用户,Class B 和实现细节隐藏在动态链接库中,使用者通过回调函数指针机制,实现对 class A 的 `CallbackA` 的重写与调用。这样既保持了接口的清晰,也封装了实现细节。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: c++函数指针与回调函数、动态库的问题