C непрозрачный указатель получил - PullRequest
4 голосов
/ 15 марта 2011

Я работаю с устаревшим интерфейсом библиотеки C (для C ++), который выставляет непрозрачные указатели как

typedef void * OpaqueObject

В библиотеке:

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

Это, конечно, абсолютно не обеспечивает безопасность типов для клиентов этой библиотеки. Должно ли изменение typedef из пустого указателя в структурный указатель работать точно так же, но обеспечить небольшую безопасность типов?

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

Есть ли какие-либо проблемы с выравниванием или другие ошибки, о которых мне нужно беспокоиться, когда я явно указываю на структуру, даже если я действительно не указываю на одну из них?

Ответы [ 3 ]

7 голосов
/ 15 марта 2011

нет гочей; эта форма предпочтительна именно из-за безопасности типов.

Нет, выравнивание здесь не проблема. Сам указатель имеет известное выравнивание, и выравнивание объекта, на который он будет указывать, имеет значение только для реализации библиотеки, а не для пользователя.

2 голосов
/ 17 марта 2012

На самом деле, класс 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 );
}

Я попробовал это и не вижу минусов.

1 голос
/ 15 марта 2011

Первое, что следует учитывать при предлагаемом курсе, это то, что вы сообщаете другим, которым, возможно, придется поддерживать код, который вы пишете. Помимо всего прочего, непрозрачные объекты - это способ C указать пользователю библиотеки, что сопровождающий библиотеки не дает абсолютно никаких гарантий относительно реализации объекта, за исключением того, что объект может использоваться с документированными функциями. Удаляя пустоту *, вы в основном объявляете миру: «Я объявляю эту реализацию, которая когда-то была непрозрачной, стабильной». Это может быть не то, что вы хотите.

Во-вторых, ИМХО, которое вы предлагаете, является своего рода половинным решением, которое никого не радует, лучший подход - разработать класс-оболочку. Это дает дополнительное преимущество, позволяя вам оборачивать функции init и destroy, которые неизбежно сопровождают непрозрачные объекты в стиле C, в конструкторах и деструкторах вашего класса. Это позволит вам обеспечить управление ресурсами, а также безопасность типов для ваших клиентов, не занимая при этом гораздо больше работы.

...