4

我正在使用将不透明指针公开为的遗留 C 库接口(到 C++)

typedef void * OpaqueObject

在图书馆:

OpaqueObject CreateObject()
{
   return new OurCppLibrary::Object();
}

这当然不会为这个库的客户提供任何类型安全。将 typedef 从 void 指针更改为结构指针是否应该完全相同,但提供少量类型安全?

typedef struct OpaqueObjectInternal_ *OpaqueObject 
// OpaqueObjectInternal_ is NEVER defined anywhere in client or library code

现在我明确指向一个结构,即使我真的没有指向一个结构,是否有任何对齐问题或其他问题需要担心?

4

3 回答 3

7

没有陷阱;正是因为类型安全,这种形式才是首选。

不,对齐在这里不是问题。指针本身具有已知的对齐方式,并且它将指向的对象的对齐方式仅与库实现有关,与用户无关。

于 2011-03-14T21:20:55.713 回答
2

实际上,C++ 类也是 C 结构。所以你可以简单地这样做:

struct Object;
struct Object* Object_Create(void);

并且,库中的 C 包装器因此:

struct Object* Object_Create(void)
{
    return new Object;
}

方法调用可能如下所示:

uint32_t Object_DoSomething( struct Object* me, char * text )
{
    return me->DoSomething( text );
}

我已经尝试过了,我没有看到任何缺点。

于 2012-03-16T20:44:12.863 回答
1

您建议的课程首先要考虑的是您与其他可能需要维护您正在编写的代码的人交流什么。最重要的是,不透明对象是向库的用户指示库维护者绝对不保证对象的实现的 C 方式,除非该对象可以与文档化的函数一起使用。通过删除 void*,您基本上是在向世界宣布,“我宣布这个曾经不透明的实现是稳定的。” 这可能不是你想要的。

其次,恕我直言,您提出的解决方案是一种让任何人都不高兴的半解决方案,更好的方法是开发一个包装类。这还有一个额外的好处,就是允许您在类的构造函数和析构函数中包装不可避免地伴随 C 风格不透明对象的 init 和 destroy 函数。这将允许您为您的客户提供资源管理和类型安全,而无需做更多的工作。

于 2011-03-15T09:21:27.337 回答