C 不透明指针陷阱
我正在使用遗留的 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
既然我明确指向一个结构,即使我实际上没有指向一个结构,是否有任何对齐问题或其他问题需要担心?
I'm working with a legacy C library interface (to C++) that exposes opaque pointers as
typedef void * OpaqueObject
In the library:
OpaqueObject CreateObject()
{
return new OurCppLibrary::Object();
}
This of course provides absolutely no type safety for clients of this library. Should changing the typedef from a void pointer to structure pointer work exactly the same, but provide a small amount type safety?
typedef struct OpaqueObjectInternal_ *OpaqueObject
// OpaqueObjectInternal_ is NEVER defined anywhere in client or library code
Are there any alignment issues or other gotchas that I have to worry about now that I am explicitly pointing to a structure, even though I'm really not pointing to one?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
没有陷阱;由于类型安全性,该形式是首选的。
不,对齐在这里不是问题。指针本身具有已知的对齐方式,并且它将指向的对象的对齐方式仅与库实现有关,与用户无关。
There are no gotcha's; that form is preferred exactly because of type safety.
No, alignment is not an issue here. The pointer itself has a known alignment, and the alignment of the object it will point at is only of concern to the library implementation, not the user.
实际上,C++ 类也是 C 结构体。所以你可以简单地这样做:
并且,库中的 C 包装器因此:
方法调用可能如下所示:
我已经尝试过这个,并且没有发现任何缺点。
Actually, a C++ class is also a C struct. So you could simply do this:
And, the C wrapper in the library thus:
A method call might look like this:
I have tried this and I see no downsides.
对于您建议的课程,首先要考虑的是您正在与可能需要维护您正在编写的代码的其他人交流什么。最重要的是,不透明对象是 C 语言的方式,用于向库的用户表明库维护者绝对不保证对象的实现,除了该对象可以与记录的函数一起使用之外。通过删除 void*,您基本上是在向世界宣布,“我宣布这个曾经不透明的实现变得稳定。”这可能不是您想要的。
其次,恕我直言,您提出的解决方案是一种让人不高兴的半解决方案,更好的方法是开发一个包装类。这样做的另一个好处是允许您在类的构造函数和析构函数中包装不可避免地伴随 C 风格不透明对象的 init 和 destroy 函数。这将使您能够为客户提供资源管理和类型安全,而无需做更多的工作。
The first thing to consider with your suggested course is what are you communicating to the others that may have to maintain the code you are writing. Above all other things opaque objects are the C way to indicate to the user of a library that the library maintainer makes absolutely no guarantee as to the implementation of an object other than that the object can be used with the documented functions. By removing the void* you are basically announcing to the world, "I declare this implementation that was once opaque to be stable." This may not be what you want.
Secondly, IMHO you are proposing is the sort of half solution that makes no one happy, a better approach is to develop a wrapper class. This has the added benefit of allowing you to wrap the init and destroy functions that inevitably accompany C style opaque objects in the constructors and destructor of you class. This will allow you to provide resource management as well as type safety to your clients with out a whole lot more work.