2009-02-17 7 views
4

Мне нужно импортировать/переводить код из одного класса C++, чтобы я мог использовать его в программе на C.Лучший способ использовать один класс C++ в программе C

Программа C большая и имеет множество зависимостей от библиотек C, открытых и закрытых.

++ .cpp файл класса C 650 линий

У меня нет никакого опыта смешивания C и C++, так что даже если бы я смотрел на одного гида о том, как это сделать, я не уверен, куда идти.

Я только использовать C++ код в нескольких местах (достаточно обособленное Useage

Я использую GCC (GCC/G ++)

Это линукс среда

Так что же я что нужно сделать, чтобы импортировать его? и это будет меньше времени, чем перевод?

Спасибо,

Майк

ответ

6

Вам нужно создать функции в C++, которые являются «Экстерн„C“», так что они могут быть отозваны из C.

Вы можете получить OO, сделав этот указатель явно (и типа пустоты *), с реализация литья указателя и пересылка в действительную функцию-член.

5

В коде C++, вы должны использовать ехЬегп «C» построить проинструктировать компилятор/компоновщик для создания совместимых связей с тем, что код C может вызвать ваш C++ кода.

extern "C" 
{ 
    void my_function_that_can_be_called_from_c() 
    { 
     // ... 
    } 
} 

код C ничего об объектах, не знает, так что вы не можете легко использовать C++ объектов из C. Общего метода заключается в манипулирование C++ объектов внутри «externed» функции.

11

Хмм, 650 строк не слишком долго - я бы переписал его. Вы, вероятно, потратите, по крайней мере, столько времени, сколько хотите, чтобы обернуть его, и вы можете легко найти результат.

1

Если вы хотите превратить класс C++ в общую библиотеку Linux, доступную для ваших программ C, this answer в предыдущем вопросе покажет вам, как с небольшим классом примеров.

5

Допустим, вы имеете следующий C++ класс:

#if __cplusplus // only C++ programs see this part of foo.h 

class foo { 
public: 
    // a couple constructors 
    foo(); 

    foo(int); 

    // and a couple methods 
    bool dosomething(); 
    bool doSomethingElse(std::string const&); 

private: 
    // a bunch of private stuff which is immaterial to the C interface 
} 

#endif 

Что вы можете сделать, это есть набор C-вызываемая функций, обмотать ++ интерфейс C:

// both C and C++ programs can see this part of foo.h 

#if __cplusplus // but C++ programs need to know that no name mangling should occur 
extern "C" { 
#endif 

struct CFoo_struct; 
typedef struct CFoo_struct foo_t; // used as a handle to a foo class pointer 

// constructors 

foo_t* CreateFoo(void); 
foo_t* CreateFoo_int(int); 

int CFooDoSomething(foo_t*); 
int CFooDoSomethingElse(foo_t*, char const*); 

#if __cplusplus 
}    // end the extern "C" block 
#endif 

Тогда выполнение в обув .cpp может выглядеть примерно так:

// in foo.cpp 
extern "C" { 

    struct CFoo_struct { 
    }; 


    // constructors 

    foo_t* CreateFoo(void) 
    { 
     foo* pFoo = new Foo; 

     // a bit of ugliness - the need for this cast could be 
     // avoided with some overhead by having the foo_t 
     // struct contain a foo* pointer, and putting a foo_t 
     // structure inside the foo class initialized with 
     // the this pointer. 

     return reinterpret_cast<foo_t*>(pFoo); 
    } 

    // something similar for CreateFoo_int()... 



    // method wrappers 

    int CFooDoSomethingElse(foo_t* pHandle, char const* s) 
    { 
     foo* pFoo = reinterpret_cast<foo*>(pHandle); 

     std::string str(s); 

     return pFoo->doSomethingElse(str); 
    } 

    // something similar for CFooDoSomething() 

} // end extern "C" block 
1

Есть различные вещи, которые вы можете сделать.

Вы можете переписать его в C. Без фактического просмотра кода я не знаю, сколько проблем было бы.Много кода C++ - это просто C с несколькими аддонами, а некоторые сильно используют шаблоны и перегруженные функции и т. Д.

Если вы этого не сделаете, вам нужно сделать так, чтобы он хорошо взаимодействовал с C. Это означает предоставление интерфейса для C и его окружение extern "C"{ ... }, поэтому компилятор C++ будет знать, чтобы сделать интерфейс C-совместимым. Опять же, не зная что-то из кода на C++, я не могу сказать, насколько это будет работать. Вам понадобится оболочка для любого из следующих решений.

Вы можете сделать это проектом на C++, объединить каждый файл C с помощью extern"C" { ... } и просто связать его. Если у вас есть файлы C++, вся компиляция должна быть C++.

Вы можете сделать отдельную библиотеку быть связаны.

То, что вы не можете сделать, это скомпилировать C и C++ вместе с функцией C основной(), или с компилятором. C++ более требователен и требует больше от функции main().

Вы всегда можете попробовать перекомпилировать файлы C, которые вы используете в качестве C++, и обернуть файлы .h для библиотек в extern "C" { ... }. Хорошо написанный C90 не так уж далек от юридического C++ (хотя стандарт C99 отошел от него), и компилятор отметит любые проблемы с конверсией, которые вы найдете.

Какая из них - лучшая идея для вас, зависит от таких вопросов, как: Насколько легко конвертировать код на C++? Насколько легко написать C-оболочку для функциональности C++, которую вы хотите? Сколько изменений вы хотите внести в код C? Насколько вы знакомы с созданием Linux-библиотеки?

Смежные вопросы