使用C而不是C++编译头

Compiling header using C, instead of C++

本文关键字:C++ 编译 使用      更新时间:2023-10-16

我有一个C++项目,我已经使用Cmake将其配置为使用Eclipse。我的问题是,我添加了一个静态C库(即svm struct/svm light),它似乎无法编译——我的猜测是,它编译为C++而不是C。

我将库添加到我的项目中,如下所示:

SET(SVM_LIGHT_SRC_DIR "../../Libraries/svm_rank")
INCLUDE_DIRECTORIES(${SVM_LIGHT_SRC_DIR})
ADD_LIBRARY(
svm_rank_lib STATIC
${SVM_LIGHT_SRC_DIR}/svm_light/svm_learn.c
${SVM_LIGHT_SRC_DIR}/svm_light/svm_common.c
${SVM_LIGHT_SRC_DIR}/svm_light/svm_hideo.c
${SVM_LIGHT_SRC_DIR}/svm_struct/svm_struct_learn.c
${SVM_LIGHT_SRC_DIR}/svm_struct/svm_struct_common.c
${SVM_LIGHT_SRC_DIR}/svm_struct/svm_struct_classify.c
${SVM_LIGHT_SRC_DIR}/svm_struct_api.c
${SVM_LIGHT_SRC_DIR}/svm_struct_learn_custom.c
)
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} svm_rank_lib)

Cmake配置似乎很好。在配置的输出中,它指定它找到我的C和C++编译器,并且它们"工作"。我使用extern将标题添加到我的一个项目文件中,如下所示:

#ifdef __cplusplus
extern "C" {
# include "svm_struct/svm_struct_common.h"
}
#endif

当我去构建我的项目时,错误在这里:

../../Libraries/svm_rank/svm_struct/../svm_struct_api_types.h:75:11: error: expected member name or ';' after declaration specifiers
double *class;    /* vector of scores that imply ranking */
~~~~~~  ^
1 error generated.

在发生错误的库头中有一个名为"class"的变量,我猜它试图使用C++而不是C编译这个库头。首先,这是错误的原因吗?如果是,我该如何着手解决这个问题?

正如已经指出的,问题的根源是C库头声明了一个名为class的变量,这是C++中的一个关键字。

一旦C++源文件引入该标头,就会出现此问题。请记住,头不是自己编译的,而只是由预处理器复制粘贴到#include处理它们的源文件中。源文件的类型决定了头中的代码是解释为C还是C++。

事实上,您在extern "C"中包装了include并没有改变这一点。它只是关闭了头中声明的C++风格的名称篡改,但代码仍然必须编译为有效的C++。

这个问题最干净的解决方案是一种被称为隔离或编译器防火墙的技术。

您必须确保与有问题的库接触的所有零件本身都是C源文件。代码的C++部分只通过该C部分的接口与库交互,而从不直接与库交互。特别是,决不能从任何头文件中#include库头。

例如:my_interface.c

#include "svm_struct/svm_struct_common.h"  /* safe to include from a .c file */
struct opaque_ {
/* you can use types from svm_struct_common in here */
};
opaque* initialize()
{
/* you can create an opaque_ on the heap and
manipulate it here, as well as give a
pointer back to the C++ part */
}
void do_stuff(opaque*)
{
/* do whatever you like with the stuff in opaque */
}

my_interface.h

/* no #includes in the header! */
/* the opaque type is only forward declared!
C++ code can obtain a pointer to it,
but cannot look inside */
struct opaque_;
typedef struct opaque_ opaque;
opaque* initialize();
void do_stuff(opaque*);

my_application.cpp

// we only include our own header, which we made sure is valid C++
extern "C" {
#include <my_interface.h>
}
void do_stuff()
{
opaque* context = initialize();
do_stuff(context);
}
double *class;    /* vector of scores that imply ranking */

类用蓝色突出显示(如果有帮助的话)。是一个保留字,表示不能将其用作变量或宏名称。尝试更改它,它应该会删除错误。

编辑

我误解了你是用C编译的,但它似乎是用C++编译的。但我仍然坚持我的答案——最好更改变量类以保持代码与C++兼容,因为类是C++中的保留字。