c++ - 如何编写用于从 C 访问 C++ 类成员的 Wrapper(具有继承和构造函数)
问题描述
在大多数问题中,我看到了一个简单类的包装器,它没有构造函数、继承,只调用一个void*
用于创建和销毁的函数以及一个 foo 函数。
对于像下面这样的结构,应该如何创建一个包装器来从C
Code 访问类成员。
myHeader.h for c++
-------------------
class childA:public parentA {private: void logger() override}
class childB:public parentB
{
private: /*some members*/
protected: /*some members*/
public:
explicit childB(childA* a);
}
class parentB
{
protected:
MyType object;
public:
boolean Init(MyType obj); /*the implmentation is object=obj*/
}
现在在C
代码中,我想访问object
. 我应该如何为此编写包装器?
Object type is a function pointer => typedef S32(*IoFunc)(Msg&);
where S32 is unsigned int, Msg is a struct.
谢谢你的帮助。
解决方案
对代码进行非客观化非常简单:
#ifdef __cplusplus
extern "C"
{
#endif
void* construct_me(/*arguments*/);
void* get_object(void* obj);
void delete_me(void* obj);
#ifdef __cplusplus
}
#endif
然后定义它们:
extern "C"
{
void* construct_me(/*arguments*/)
{
return static_cast<void*>(new parentB(/*arguments*/));
}
void* get_object(void* obj)
{
return static_cast<void*>(&(static_cast<parentB*>(obj)->object));
}
void delete_me(void* obj)
{
delete static_cast<parentB*>(obj);
}
}
如果该类型可以在 C 中使用,那么您可以这样做:
Type get_object(void* obj)
{
return static_cast<parentB*>(obj)->object;
}
而不是将其转换为void*
.
继承不会改变任何事情。这是相同的机制,除了如果您有虚函数,您仍然应该为继承的类包装所有虚函数(即使 A 从 B 继承,将 A* 转换为 void* 为 B* 也是 UB)。
PS:我认为这与提供的链接中的答案没有什么不同。
推荐阅读
- ruby-on-rails - AWS 错误:未配置“生产”数据库
- html - Thymeleaf 表行划分为单独的页面
- angular - 如何使用 angular 中的 highcharts 创建如下图
- php - 如何避免 PHP 嵌套 if...else... 条件并编写干净、易于理解的代码?
- php - Magento 2:通过税获得产品价格/特价?
- sql - 在 SQL 中,如何按用户拥有的项目数对用户进行细分?(红移)
- javascript - 事件监听器点击不适用于 ejs 文件
- javascript - 如何使对象在记录时表现为单个许可值,但在分配给变量时充当对象意味着赋予其参考?
- events - 在本地发出 NestJS 事件(进程内 EventPattern 触发器)
- powershell - 将新用户添加到 SharePoint 对象时,集合大小固定错误