2011-03-14 65 views
4

我用传统的C库接口的工作(以C++),其公开不透明的指针作为ç不透明指针陷阱

typedef void * OpaqueObject 

在图书馆:

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

当然,这绝对不提供为该图书馆的客户提供类型安全。应该从void指针改变typedef到结构指针的工作是完全一样的,但提供少量的类型安全?

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

有没有对齐的问题,或者我对现在担心其他陷阱,我明确地指向一个结构,即使我真的不指向一个?

+3

在** C **中没有叫'new'的操作符! – Mahesh 2011-03-14 21:16:28

+2

@Mahesh:我认为OP是用C++封装了一个C库; 'new'发生在C++中(由'OurCppLibrary'限定符推断出来的) – fbrereto 2011-03-14 21:19:59

+2

void *作为一个不透明的对象是非常有意义的 - 你的事物的结尾不会弄乱对象,而且他们知道该怎么做用它做。如果有的话,使其成为'void *'使得它更安全,只要你像他们描述的那样使用它的API。 – James 2011-03-14 21:40:08

回答

7

没有疑难杂症;这种形式由于类型安全性而是首选。

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

1

您建议的课程首先要考虑的是,您与其他人沟通的内容可能需要维护您正在编写的代码。除了所有其他事物之外,不透明对象是C方式向库的用户指示库维护者完全不能保证对象的实现,而不是该对象可以与记录的功能一起使用。通过删除void *,你基本上向全世界宣布,“我声明这个曾经不透明的实现是稳定的。”这可能不是你想要的。其次,恕我直言,你提出的是一种让人无法开心的半解决方案,更好的方法是开发一个包装类。这还有一个额外的好处,就是允许你将不可避免地伴随C风格不透明对象的init和destroy函数包装在你的类的构造函数和析构函数中。这将允许您提供资源管理以及为您的客户提供安全类型,并完成更多的工作。

+1

我不明白为什么结构指针不透明。没有定义客户端可以访问的结构(或者实现,就此而言)。关于包装类,这是针对纯粹的C消费者的。 – 2011-03-15 17:08:55

+0

看起来我很困惑这个例子使用C++构造和标题说的是C++,另外,我建议不要命名结构OpaqueObjectInternal_ Internal和尾部下划线都是公共约定,它们表示私有实现。仔细阅读注释使我相信这个结构是内部实现而不是不透明指针。对我们来说这可能是一个教训;-) – ltc 2011-03-16 06:51:53

+0

有人编辑了从C到C++的标题。你会命名结构? C接口知道每种类型都有不同的结构。 – 2011-03-16 21:48:09

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); 
} 

我已经试过这我没有看到任何缺点。