我正在尝试将供应商的库与我的C++应用程序结合使用.该库主要基于C,这通常不是extern "C"选项的问题,但我遇到了C++编译器不接受的问题.
我将我的代码简化为以下示例文件.header.h表示来自suppier库的头文件,main.c/cpp是我自己的文件.我真正的应用程序是一个C++应用程序,所以我想让它与main.cpp一起使用.
header.h(注意这一行u64 u64;):
#ifndef HEADER_H
#define HEADER_H
#include <stdint.h>
typedef uint64_t u64;
union teststruct {
u64 u64;
struct {
u64 x:32;
u64 y:32;
} s;
};
#endif
Run Code Online (Sandbox Code Playgroud)
main.c中:
#include <stdio.h>
#include "header.h"
int main() {
union teststruct a;
a.u64=5;
printf("%x\n", a.u64);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
main.cpp(与main.c相同,但有一个额外的extern "C"声明):
#include <stdio.h>
extern "C" {
#include "header.h"
}
int main() {
union teststruct a;
a.u64=5;
printf("%x\n", a.u64);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用该行编译main.c.
gcc -o test main.c
Run Code Online (Sandbox Code Playgroud)
编译没有问题.但是,使用带有命令的g ++编译器编译C++版本
g++ -o test main.cpp
Run Code Online (Sandbox Code Playgroud)
给出以下编译器错误:
In file included from main.cpp:12:0:
header.h:11:9: error: ‘u64’ does not name a type
u64 x:32;
^
header.h:12:9: error: ‘u64’ does not name a type
u64 y:32;
^
Run Code Online (Sandbox Code Playgroud)
问题是供应商对类型和变量名称使用相同的名称(u64),这似乎是一个坏主意,但gcc显然接受它.我不想更改库(即header.h)因为它非常大,这在代码中发生了很多,我偶尔会得到它的更新.有没有办法让g ++接受这种组合,或者修改main.cpp以使其编译而不改变header.h的方法?
Sto*_*ica 48
teststruct用C++定义一个范围.您可以形成合格的ID teststruct::u64.因此,名称查找的语言规则考虑到了这一点,允许类和联合的成员隐藏外部作用域中的标识符.一旦u64 u64;介绍,不合格的u64不能指全球::u64,只指会员.该成员不是一个类型.
在C union teststruct中没有定义范围.该字段只能用于成员访问,因此永远不会出现冲突.因此,该字段不需要隐藏文件范围类型标识符.
据我所知,没有什么可以做的,以便轻松解决它.该库(它是一个完全有效的C库)不是有效的C++库.没有什么不同,如果它使用new或try作为变量名称.它需要进行调整.
Max*_*hof 39
看来你有一个在C++中是非法的头文件,所以你不能#include在编译为C++的代码中使用它.如果您无法对库头文件进行更改(例如,向您的库供应商抱怨),那么最直接的选择是在库周围编写一个与C++兼容的瘦包装:
为了隔离对C头你的C++代码,创建一个Wrapper.h和Wrapper.c,其中.h有效纳入C++,并没有包括header.h,并提供了你需要的库交互的所有类型和功能.然后,在中.c,您可以#include "header.h"实现所有调用(以及您需要做的任何事情以安全地在类型之间进行转换).这显然必须编译为C,而不是C++.
| 归档时间: |
|
| 查看次数: |
4021 次 |
| 最近记录: |