鱼C论坛

 找回密码
 立即注册
查看: 117|回复: 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呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-21 19:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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