将struct层次结构包装到C ++类中

时间:2018-04-25 15:19:37

标签: c++ c

如何将这个层次结构包含在包含调用其C等价物的成员函数的C ++类中?

C经常使用大量的黑客来获得继承层次结构。其中之一是在Linux内核中大量使用的container_of宏。我正在使用以这种样式编写的现有C库,我想将结构层次结构调整为由C ++包装的结构。为了便于说明,我将使用以下结构层次结构。

#include <cstdio>
#include <iostream>
#include <cstddef>

#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})

extern "C" {
    struct a;

    typedef void (*callback_t)(struct a *self);

    struct a {
        callback_t cb;
    };

    struct b {
        struct a a;
        const char * name;
    };

    void handle_event(struct a *self) {
        self->cb(self);
    };

    void process_event(struct a * a) {
        handle_event(a);
    }

    void some_a_operation(struct a * self) {
        printf("some operation called on a @ %p\n", self);
    }

    void some_b_operation(struct b * self) {
        printf("some operation called on a @ %p\n", self);
    }

    void c_callback_handler(struct a * a)
    {
        struct b * b = container_of(a, struct b, a);
        printf("%s\n", b->name);
    }
};

如果上述代码没有变化,我可以看到以下方法。

使用包装器

的委派

这解决了struct a重复的先前示例问题,但代价是显着复杂。

class A {
public:
    A() {
        A_Wrap = new A_wrapper {{A::Cb}, this};
        A_Obj = &A_Wrap->a_member;
    }
    virtual ~A() {
        delete A_Wrap;
    }
    void OperationA() {
        some_a_operation(A_Obj);
    }
    virtual void InstanceCb() {};
    // member functions access struct a via A_Obj
protected:
    struct A_wrapper {
        a a_member;
        A * A_member;
    };
    A_wrapper* A_Wrap;
    a * A_Obj;
private:
    static void Cb(a * self) {
        A_wrapper * a_wrapper = container_of(self, A_wrapper, a_member);
        a_wrapper->A_member->InstanceCb();
    }
};

class B: public A {
public:
    B() {
        delete A_Wrap;
        B_Wrap = new B_wrapper {{&B::Cb}, this};
        A_Obj = &B_Wrap->b_member.a;
        B_Obj = &B_Wrap->b_member;
    }
    virtual ~B() {
        A_Wrap = nullptr;
        delete B_Wrap;
    }
    void OperationB() {
        some_b_operation(B_Obj);
    }
    virtual void InstanceCb() {
        std::cout << "B class" << std::endl;
    };
    // member functions access struct a via A_Obj
protected:
    struct B_wrapper {
        b b_member;
        B * B_member;
    };
    B_wrapper * B_Wrap;
    b * B_Obj;
private:
    static void Cb(a * self) {
        b * b_contained = container_of(self, b, a);
        B_wrapper * b_wrapper = container_of(b_contained, B_wrapper, b_member);
        b_wrapper->B_member->InstanceCb();
    }
};

使用示例

int main(int argc, char **argv) {
    // C usage
    const char * b_name = "b struct";
    struct b b_cexample = {
            {c_callback_handler}, b_name
    };

    process_event(&b_cexample.a);
    some_a_operation(&b_cexample.a);
    some_b_operation(&b_cexample);


    // C++ usage example
    B b_cppexample;
    b_cppexample.InstanceCb();
    b_cppexample.OperationA();
    b_cppexample.OperationB();
}

0 个答案:

没有答案