2012-01-24 2 views
4

У меня есть файл заголовка для того, что должно быть объединенным C++ и C API. Часть C завернута в extern "C", но сами декларации очень сильно отличаются от C; например:Обтекание ссылок C++ в C API

foo::Bar& Foo_Baz_GetBarOfQux(void *_self, const foo::Qux &qux); 

Есть ли способ на самом деле использовать его в форме plain C? Очевидно, я не могу использовать этот заголовок, но, возможно, я могу переопределить его как-то:

/* type? */ Foo_Baz_GetBarOfQux(void*, const /* type? */); 

озадачивает меня, как объявлять типы этих ссылок (если это возможно).

P.S. Я знаю, что может написать свою собственную C обертку на вершине этого: я объявляю классы в непрозрачных структурах:

typedef struct foo_bar foo_bar_t; 
typedef struct foo_baz foo_baz_t; 
typedef struct foo_qux foo_qux_t; 

, а затем написать C-как функцию, которая облегает выше функции:

extern "C" 
foo_bar_t* 
foo_baz_get_bar_of_qux(
    foo_baz_t* baz, 
    foo_qux_t* qux) 
{ 
    return (foo_bar_t*) Foo_Baz_GetBarOfQux(baz, *(foo::Qux*)qux); 
} 

Но мне интересно, могу ли я напрямую использовать оригинал Foo_Baz_GetBarOfQux().

+0

AFAIK niether У вас есть оператор разрешающей способности '::' в C, и вы можете возвращать ссылки, такие как 'Bar &', поэтому вы не можете использовать функцию как есть в обычном C –

+0

@ another.anon.coward Правильно, но, возможно, я могу переопределить Это? (Обновлен вопрос.) –

+0

Я думаю, должно быть возможно, если вы определяете типы C (structs?) С тем же самым расположением памяти, что и foo :: Bar и foo :: Qux. – Alex

ответ

7

Нет, вы не можете использовать Foo_Baz_GetBar() непосредственно, вызовов к функции члена в c++ предполагает неявно обходе this указателя, который не существует в вашем c кода.

+1

Ну, это моя вина; Я попытался подготовить упрощенный пример и потерял этот указатель. Я изменяю вопрос. –

2

В общем, было бы лучше использовать непрозрачные структуры.

В интерфейсе «C» кода никогда не пытайтесь заглянуть внутрь непрозрачной структуры, просто покорно передайте указатели.

В разделе «C++» вы должны определить структуру и на самом деле заполнить ее соответствующим образом (я бы избегал слепого придания типов).

Конечно, часть «C++» не должна отображаться в заголовке «C», чтобы не смущать компилятор C.

+0

Да, это единственный вариант. Я не могу реально заполнять данные на стороне C++, потому что все, что у меня есть, это заголовок и C++ «классы», объявляют несколько встроенных «методов», которые фактически вызывают те же «Foo_Baz_GetBarOfQux()» и подобные функции, которые имеют C-ссылку, но C++ типы. Пока что идиот о разглашении разыгрыша '' * (foo :: Qux *) qux'' работал нормально. –