C ++ код и объекты из C? - PullRequest
7 голосов
/ 29 июня 2009

Есть ли простой способ работы с объектами C ++ непосредственно из C? Я хочу представить некоторые классы от C ++ до C или FFI (интерфейс сторонних функций). Конечно, я могу написать такую ​​вещь:

class Foo{
....
};

void *make_foo(...){
Foo *ptr = new Foo(..)

return static_cast<void *>(ptr);
}

..

int *foo_method1(void *fooptr, ...){
Foo *ptr = static_cast<Foo*>(fooptr);
}

а есть более простой способ?

Ответы [ 5 ]

8 голосов
/ 29 июня 2009

Это, вообще говоря, самый простой способ.

Также помните, что вам нужно будет использовать extern "C" также для всех ваших методов "обертки" в C.

7 голосов
/ 29 июня 2009

Ты почти там. Добавьте extern "C" к своим автономным функциям, чтобы отключить искажение имени компилятора C ++ .

Например:

extern "C" void *make_foo(...){
  Foo *ptr = new Foo(..)

  return static_cast<void *>(ptr);
}
1 голос
/ 29 июня 2009

Если это возможно, тогда ваши классы должны быть производными от структуры. Затем вы можете использовать указатели на эту структуру в коде C:

// C++ code
extern "C" struct Cfoo {};
extern "C" struct Cbar {};

class foo : public Cfoo {};
class bar : public Cbar {};

// C API
extern "C" {
    struct Cfoo;
    struct Cbar;
}

Это не является строго ошибкой, однако gcc по крайней мере предупреждает о конвертации между указателями с разными типами.

void foo (void) {
    struct Cfoo * pf;
    struct Cbar * pb;
    pf = pb;        // gcc warns
}

Если вы не можете наследовать, используйте аналогичную идею, но пусть структура C хранит указатель на объект C ++ и снова просто объявляет структуры в API C:

// C++ code
class foo {};
class bar {};

extern "C" struct Cfoo { foo * pFoo; };
extern "C" struct Cbar { bar * pBar; };

// C API
extern "C" {
    struct Cfoo;
    struct Cbar;
}

Недостатком здесь является то, что нужно заботиться о времени жизни объекта Cfoo и Cbar.

1 голос
/ 29 июня 2009

Вы можете использовать Verrazano / Fetter для генерации CFFI привязок для кода C ++. Но для этого требуется GCC-XML, и я не уверен в его переносимости.

1 голос
/ 29 июня 2009

Нет более простого способа сделать это. Вы можете использовать SWIG , чтобы перейти на другой язык с пользовательскими типами, которые представляют собой нечто большее, чем совокупность данных, но для преобразования в C вам придется использовать представление C об объектах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...