我正在开展一个需要与sheepdog合作的学校项目。 Sheepdog提供了一个c api,可以连接到牧羊犬服务器。 首先,我使用以下内容创建c源文件(test.c):
#include "sheepdog/sheepdog.h"
#include <stdio.h>
int main()
{
struct sd_cluster *c = sd_connect("192.168.1.104:7000");
if (!c) {
fprintf(stderr, "failed to connect %m\n");
return -1;
}else{
fprintf(stderr, "connected successfully %m\n");
}
return 0;
}
然后我使用以下命令编译没有错误
gcc -o test test.c -lsheepdog -lpthread
但我需要的是将它与c ++项目一起使用,所以我创建了一个cpp文件(test.cpp),其中包含以下内容:
extern "C"{
#include "sheepdog/sheepdog.h"
}
#include <stdio.h>
int main()
{
struct sd_cluster *c = sd_connect("192.168.1.104:7000");
if (!c) {
fprintf(stderr, "failed to connect %m\n");
return -1;
}else{
fprintf(stderr, "connected successfully %m\n");
}
return 0;
}
现在,当我使用以下命令编译时:
g ++ -o test test.cpp -lsheepdog -lpthread
答案 0 :(得分:6)
您不能将extern "C"
包裹在标题周围,并期望它在C ++程序中编译。例如,标头sheepdog_proto.h
使用名为new
的参数;这是C ++中的关键字,因此无法以C ++编译。该库不是为从C ++调用而设计的。
答案 1 :(得分:1)
我同意@PeteBecker。通过快速浏览Google,我不确定是否有一个简单的解决方案。 Sheepdog使用的C功能和名称不能很好地适应C ++。你可能需要相当广泛地攻击牧羊犬。例如:
inline
函数从sheepdog_proto.h
移出到新的C文件中,将原型保留在原位。这应该处理offsetof
错误,例如this answer中讨论的错误。 #define new not_a_keyword_new
中sheepdog/sheepdog.h
以及为了使其编译而必须进行的任何其他特定更改。来自专家的更多建议here。
答案 2 :(得分:0)
由于牧羊犬的设计不能用于C ++,你应该用C语言构建一个小包装器来调用牧羊犬的函数,并只从你的c ++代码中调用包装器。写一些包装器的一些提示:
void *
非常适合传递不透明指针提取器可以帮助访问命名严重的成员。如果一个struct有一个名为new
的成员(类型为T),你可以写:
T getNew(void *otherstruct); // declaration in .h
和
T getNew(void *otherstruct) { // implementation in a c file
return ((ActualStruct *) otherstruct)->new;
}
根据牧羊犬(我不知道)和您想要使用的部分的复杂程度,它可能是也可能不是可接受的解决方案。但这是我尝试面对这样一个问题的方式。
无论如何,链接器允许在静态链接或动态链接中混合用C和C ++编译的模块。