鱼C论坛

 找回密码
 立即注册
查看: 543|回复: 1

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

[复制链接]
发表于 2024-10-10 09:30:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

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

各位大神,请问这样怎么实现ClassA 跟B呢?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-10-10 09:30:48 | 显示全部楼层
要实现 Class A 和 Class B 之间的回调关系以及动态库的封装,主要的思路是利用函数指针或接口来解耦,实现数据传递与回调。以下是一个简单的实现示例说明如何实现这个功能。

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

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

  8. // 提供一个函数指针类型,指向 CallbackA
  9. typedef void(*CallbackType)(int);
复制代码


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

  1. // Class B - 实现库的内部逻辑
  2. class B {
  3. private:
  4.     CallbackType m_callback;
  5.    
  6. public:
  7.     B() : m_callback(nullptr) {}

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

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

  15.         // 调用回调函数
  16.         if (m_callback) {
  17.             m_callback(data);
  18.         }
  19.     }
  20. };
复制代码


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

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

  1. // 动态库接口,供用户实现并导出
  2. extern "C" {
  3.     B* CreateBInstance() {
  4.         return new B();
  5.     }
  6.    
  7.     void DestroyBInstance(B* b) {
  8.         delete b;
  9.     }

  10.     void BSetCallback(B* b, CallbackType callback) {
  11.         if (b) {
  12.             b->SetCallback(callback);
  13.         }
  14.     }
  15.    
  16.     void BDoSomething(B* b) {
  17.         if (b) {
  18.             b->DoSomething();
  19.         }
  20.     }
  21. }
复制代码


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

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

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

  2. class MyA : public A {
  3. public:
  4.     void CallbackA(int data) override {
  5.         std::cout << "Callback received data: " << data << std::endl;
  6.     }
  7. };

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

  12. int main() {
  13.     B* bInstance = CreateBInstance();
  14.     if (bInstance) {
  15.         BSetCallback(bInstance, MyCallback);
  16.         BDoSomething(bInstance);
  17.         DestroyBInstance(bInstance);
  18.     }
  19.     return 0;
  20. }
复制代码


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-8 00:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表