我需要将一个C++类的代码导入/翻译,以便我可以在C程序中使用它。
C程序很大,并且有许多对开放和封闭C库的依赖。
C++类.cpp文件有650行
我没有混合使用C和C++的经验,即使我已经查看了一份指南,我仍然不确定该怎么做。
我只需要在几个地方使用C++代码(相当隔离的用法)
我正在使用gcc(gcc/g++)
这是一个Linux环境
那么我需要做什么才能导入它?是否比翻译更省时间?
谢谢,
迈克
您需要在C++中创建extern "C"函数,以便可以从C中调用。
您可以通过将this指针显式化(并且类型为void *)来实现OO,实现将指针转换并转发到实际成员函数。
在您的C++代码中,必须使用extern "C"结构来指示编译器/链接器生成兼容的链接,以便C代码可以调用您的C++代码。
extern "C"
{
void my_function_that_can_be_called_from_c()
{
// ...
}
}
C代码对于对象一无所知,因此您无法轻松地在C中使用C++对象。一种常用的技术是在“externed”函数内部操作C++对象。
假设你有以下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
// 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
那么,在foo.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
有很多事情可以做。
你可以用C重写它。但是如果没有看到代码,我不知道这会有多大的麻烦。许多C++代码只是带有一些附加功能的C,而有些则大量使用模板和重载函数等。
如果你不这样做,你需要让它与C良好地通信。这意味着为C提供一个接口,并用extern "C"{ ... }
将其包围起来,以便C++编译器知道如何使接口与C兼容。同样,如果不了解C++代码的某些内容,我无法告诉你这需要多少工作量。你需要为以下两种解决方案之一编写包装器。
你可以将其作为C++项目,用extern"C" { ... }
包围每个C文件,然后链接它。如果有任何C++文件,则整个编译必须是C++。
你可以制作一个单独的库来链接。
你不能在C主函数中或使用C编译器将C和C++编译在一起。C++更加苛刻,需要主函数提供更多支持。
你可以尝试将你正在使用的C文件重新编译为C++,并将库的.h文件包装在extern "C" { ... }
中。良好编写的C90与合法的C++相差不远(虽然C99标准有所偏移),编译器会标记任何转换问题。
哪种方法对你来说最好取决于以下问题: 将C++代码转换为多么容易? 编写C包装器以获取所需的C++功能有多容易? 你愿意对C代码进行多少更改? 你对制作Linux库有多熟悉?