我有一堆C代码。我无意将它们转换为C ++代码。
现在,我想调用一些C ++代码(我不介意修改C ++代码,以便它们可以通过C代码调用)。
class Utils {
public:
static void fun();
}
class Utils2 {
public:
static std::wstring fun();
}
如果我倾向于用以下语法调用它们,它们就不会编译(我使用的是VC ++ 2008,扩展名为.c的C代码文件)
Utils::fun();
// Opps. How I can access std::wstring in C?
Utils2::fun();
有什么建议吗?
答案 0 :(得分:8)
// c_header.h
#if defined(__cplusplus)
extern "C" {
#endif
void Utils_func();
size_t Utils2_func(wchar_t* data, size_t size);
#if defined(__cplusplus)
}
#endif
//eof
// c_impl.cpp
// Beware, brain-compiled code ahead!
void Utils_func()
{
Utils::func();
}
size_t Utils2_func(wchar_t* data, size_t size)
{
std::wstring wstr = Utsls2::func();
if( wstr.size() >= size ) return wstr.size();
std::copy( wstr.begin(), wstr.end(), data );
data[wstr.size()] = 0;
return str.size();
}
//eof
答案 1 :(得分:6)
包装器
怎么样?extern "C" void Utilsfun(int i){Utils::fun(i);}
<强>更新强>
这就是如何从C调用C ++函数,但从C访问std :: wstring是另一回事。
如果您真的想从C代码中操作C ++类,那么您可以创建一个API,其中使用C ++函数对类进行操作,并使用void指针将其传递回C.我已经看过它,但它并不理想
extern "C"
{
void * ObjectCreate(){return (void *) new Object();}
void ObjectOperate(void *object, char *parameter){((Object*)object)->Operate(parameter);}
void ObjectDelete(void *object){delete ((Object*)object);}
}
管理创建和删除时,您必须非常小心。
答案 2 :(得分:1)
我认为唯一的解决方案是将它们包装在C ++代码中的C风格全局函数中,如:
extern "C" int Util2_Fun() { return Util2::Fun(); }
我想你也可以使用一些令人讨厌的变体声明全局函数指针作为外部函数:
extern int (*Utils2_Fun)()=(int *())(Util2::Fun);
然后使用这个指针直接从C包调用函数指针,但没有什么可以推荐这种方法。
答案 3 :(得分:1)
最常见的解决方案是为C ++函数编写C接口。这是使用extern "C" { ... }
声明的C ++代码。这些包装函数可以自由调用他们喜欢的任何C ++代码,但由于它们被声明为extern "C"
,因此它们不会受到名称修改(你不能在这里做命名空间或重载)。
这应该与你的C文件链接,你很高兴。
即,头文件包含
#ifdef __cplusplus
extern "C" {
#endif
void wrapper1(void);
int wrapper2(int x);
char* wrapper3(int y);
#ifdef __cplusplus
}
#endif
需要ifdef来保护C编译器免受extern "C"
的攻击。
然后在C ++源代码中实现它们
void wrapper1(void) { Util::funcOne(); }
int wrapper2(int x) { return Util::funcTwo(x); }
char* wrapper3(int y) { return Util::funcThree(y); }
答案 4 :(得分:1)
在C ++代码中创建一个包装函数:
extern "C" void Wrapper() {
Utils2::fun();
}
然后在你的C代码中:
extern void Wrapper();
int main() {
Wrapper();
return 0;
}
答案 5 :(得分:0)
您可以使用extern "C"
构造从C中调用C ++。
答案 6 :(得分:0)
如果按照人们的说法(使用extern“C”),请注意您只将对象传递给将在C中编译的C函数。
答案 7 :(得分:0)
您的C代码中的c ++对象没有任何实际用途,因此您可能希望为C ++代码创建某种“C Binding”,其中包含一些可从中调用的普通函数。 C,只返回普通的C数据类型。然后,您的包装函数可以调用各种类和对象等。但是,它们为可以从C中使用的对象提供了更简单的C-Style接口来弥补差距。在某些情况下,你也可以使用函数指针给C访问静态方法,但通常最简单的方法就是创建包装器,恕我直言。
答案 8 :(得分:0)
您可以编写全局extern“C”包装函数或使用函数指针另外创建C已知的静态类函数.C ++代码可以将这些指针放在全局结构中,或者在将C函数调用为C时将它们传递给C一个参数。此外,您可以建立一个注册表,其中C代码可以通过提供字符串ID从C ++请求函数指针。我使用了所有这些品种。
答案 9 :(得分:0)
如果你控制了所有的源代码,我就不会费心试图将它的一部分保留为C.它应该像C ++一样可编译(或者很容易改变以实现它)。这并不意味着您需要将其重写为C ++,只需将其编译即可。这样你可以使用C ++的任何部分都有意义。随着时间的推移,C代码变得更像C ++,但这会在需要时缓慢发生。
当然,如果您因其他原因需要在C中保持可编辑状态,则不适用。
答案 10 :(得分:-3)
C是C ++的一个子集.. 所以你不能在C中调用c ++类成员和命名空间。