C接口中句柄的正确类型

我正在创建一个隐藏DLL文件中的某些function的C api。

由于内部的所有内容都是C ++,因此大多数函数都可以处理直接映射到API内部的指针的句柄。

为了获得这些句柄的某种程度的类型安全性,我将它们定义为:

typedef struct MyType1* MyType1Handle; typedef struct MyType2* MyType2Handle; 

我实际上并没有在任何地方定义MyType1或MyType2,因为我只将它们用作指针,并在api内部对实际指针类型进行类型转换。

我的问题是,当我在Visual Studio的clr项目中使用我的库时,我得到了这个warning: unresolved typeref token (token) for 'type'; image may not run. warning: unresolved typeref token (token) for 'type'; image may not run.

http://msdn.microsoft.com/en-us/library/h8027ys9(VS.80).aspx

它起作用并没什么大不了的,但它看起来不专业。

我不喜欢使用void *:

 typedef void* MyType1Handle; typedef void* MyType2Handle; 

这使得可以调用想要MyType1Handle和MyType2Handle的函数,因为它们实际上是相同的类型。

我不想使用的另一种方法是这样的

 typedef int MyType1Handle; typedef int MyType2Handle; 

只要int和指针具有相同的大小,这就可以正常工作,但情况并非总是如此,似乎没有万无一失的方法可以获得特定于平台的指针大小整数。 它也具有与void *相同的类型安全问题。

我尝试的另一种方法就是这样做:

 struct MyType1{}; typedef struct MyType1* MyType1Handle; 

这在C中不起作用,因为空结构是无效的C代码。 我当然可以用虚拟成员扩展我的结构,但似乎应该有更好的方法来做到这一点。

所以我的问题归结为:

你如何以最兼容的方式指定这种类型?

如果你看一下微软如何定义它的winapi句柄(winnt.h),它实际上是这样的:

 struct HWND__ { int unused; }; typedef struct HWND__ *HWND 

实际上他们有一个宏:

 #define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name 

所以..这似乎是一种常见的做法。 不幸的是,我不能提出另一个建议,除了你已经提到的这个,但我希望无论如何它对你有所帮助。

使用不透明的结构。 在许多情况下,在C中定义库的接口时,这是一个好主意:它改进了模块化,隐藏了不必要的细节

正如JamieH所说,你通过声明 – 但不是定义 – 结构来获得一个不透明的结构。 将指向不透明结构的指针作为参数传递给库函数并将它们作为值返回是完全有效的。 但是,库的用户无法创建或修改opaque结构的对象,因为它的大小和内容是未知的。

C标准库和许多其他人已经使用了这种方法,所以它应该是熟悉的。 一个典型的例子是使用FILE *fopen()创建并初始化结构并返回指向它的指针, fclose()清理并释放它,所有其他i / o函数从传入的FILE *获取它们的上下文。

我想你可以声明,但不能定义源结构:

struct MyType1;

typedef struct MyType1 * MyType1Handle;

类似主题: 句柄比较:空类与未定义类相比无效*