简体   繁体   English

使用extern“C”在c ++程序中包含标题时出错

[英]error when using extern “C” to include a header in c++ program

I am working on a school project which requires to work with sheepdog . 我正在开展一个需要与牧羊犬一起工作的学校项目。 Sheepdog provides ac api which enables you to connect to a sheepdog server. Sheepdog提供ac api,可以连接到牧羊犬服务器。 First i create c source file(test.c) with the following content : 首先,我使用以下内容创建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;
}

then i compile with no error using the following command 然后我使用以下命令编译没有错误

gcc -o test test.c -lsheepdog -lpthread gcc -o test test.c -lsheepdog -lpthread

But what i need is to use it with c++ project so i created a cpp file(test.cpp) with the following content : 但我需要的是将它与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;
}

now, when i compiled using the following command : 现在,当我使用以下命令编译时:

g++ -o test test.cpp -lsheepdog -lpthread g ++ -o test test.cpp -lsheepdog -lpthread

I got this error : 我收到了这个错误: 编译错误消息

You can't just wrap extern "C" around a header and expect it to compile in a C++ program. 你不能只在标题周围包装extern "C" ,并期望它在C ++程序中编译。 For example, the header sheepdog_proto.h uses an argument named new ; 例如,标头sheepdog_proto.h使用名为new的参数; that's a keyword in C++, so there's no way that will compile as C++. 这是C ++中的关键字,所以没有办法像C ++一样编译。 The library was not designed to be called from C++. 该库不是为从C ++调用而设计的。

I agree with @PeteBecker. 我同意@PeteBecker。 From a quick look around Google, I am not sure there is an easy solution. 通过快速浏览Google,我不确定是否有一个简单的解决方案。 Sheepdog is using C features and names that don't port well to C++. Sheepdog使用的C功能和名称不能很好地适应C ++。 You might need to hack sheepdog fairly extensively. 你可能需要相当广泛地攻击牧羊犬。 For example: 例如:

  • move the inline functions out of sheepdog_proto.h into a new C file, leaving prototypes in their place. inline函数从sheepdog_proto.h移出到一个新的C文件中,将原型保留在原位。 This should take care of the offsetof errors, eg, discussed in this answer . 这应该处理错误的offsetof ,例如,在本答复中讨论。
  • #define new not_a_keyword_new in sheepdog/sheepdog.h sheepdog/sheepdog.h #define new not_a_keyword_new#define new not_a_keyword_new

and whatever other specific changes you have to make to get it to compile. 以及为了使其编译而必须进行的任何其他特定更改。 More advice from the experts here . 从专家们更多的建议在这里

As sheepdog was not designed to be useable from C++ you should build a tiny wrapper in C language to call the functions from sheepdog and only call the wrapper from your c++ code. 由于牧羊犬不是设计用于C ++,你应该用C语言构建一个小包装器来调用牧羊犬的函数,并只从你的c ++代码中调用包装器。 Some hints to write such a wrapper: 写一些这样的包装器的一些提示:

  • void * is great to pass opaque pointers void *非常适合传递不透明指针
  • extractors can help to access badly named members. 提取器可以帮助访问命名严重的成员。 If a struct has a member called new (of type T), you could write: 如果一个struct有一个名为new的成员(类型为T),你可以写:

     T getNew(void *otherstruct); // declaration in .h 

    and

     T getNew(void *otherstruct) { // implementation in ac file return ((ActualStruct *) otherstruct)->new; } 

Depending on the complexity of sheepdog (I do not know it) and the part you want to use, it may or not be an acceptable solution. 根据牧羊犬(我不知道)和你想要使用的部分的复杂程度,它可能是或不是一个可接受的解决方案。 But it is the way I would try facing such a problem. 但这是我尝试面对这样一个问题的方式。

Anyway, the linker allows mixing modules compiled in C and in C++, either in static linking or dynamic linking. 无论如何,链接器允许混合用C和C ++编译的模块,无论是静态链接还是动态链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM