- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 C++ 类 key_gen,它有一些 paillier_prvkey_t 类型的数据成员。问题是我不能在我的头文件中包含 paillier 库(用 c 编写),比如 key_gen.h。但是我可以使用
将它包含在我的 key_gen.cpp中extern "C"{
#include<paillier.h>
}
我正在使用 cygwin 来运行我的代码,我使用如下命令行:
g++ Key_Gen.cpp -L/cygdrive/c/cygwin/home/Win7/libpaillier -l:libpaillier.a -
-lgmpxx -lgmp
只要我将 paillier header 包含到我的 header 文件中,cygwin 就会在我运行代码时发出警报。
错误包含多行,例如:
In file included from Key_Gen.h:13:0,
from Key_Gen.cpp:2:
/usr/local/include/paillier.h:63:3: note: previous declaration as ‘typedef
struct paillier_pubkey_t paillier_pubky_t’} paillier_pubkey_t;
^
谁能告诉我如何解决这个问题?
最佳答案
当您告诉 C 或 C++ 编译器处理文件 foo.cpp
时,编译的第一阶段是预处理,它扩展宏、替换定义和扩展预处理器指令,例如#include
。
在早期,预处理器是一个单独的程序,它会即时生成输出:C 编译器本身并不知道 #include
,它看到的只是一个流代码。
如今,预处理器通常是编译器(gcc、MSVC 等)不可或缺的一部分,但您在命令行上指定的每个源文件的单流效果保持不变,您仍然可以访问编译器以将预处理的输出生成为单个中间文件,以便您可以查看正在进行的翻译(gcc/g++ 的 -E 选项)。所以如果你写:
// Foo.h
int foo;
// Bar.cpp
#include "Foo.h"
int bar;
#include "Foo.h"
编译器看到的是一个连续的流:
/* "Bar.cpp" from command line */
// Bar.cpp
/* "Foo.h" from Bar.cpp:2 */
int foo;
/* end "Foo.h" */
int bar;
/* "Foo.h" from Bar.cpp:4 */
int foo;
/* end "Foo.h" */
/* end "Bar.cpp" */
#include
,#include
进行重复数据删除,因此多个包含会产生重复数据。如果您想将 paillier.h
添加到您自己的 .h
文件中,您需要防止这种重复。有两种常见的方法可以做到这一点。
在 .h 文件的开头使用预处理器指令 #pragma,GNU C 和 C++ 编译器都能理解:
#pragma once
优点:预处理器检测到 #include
语句中的重复项,因此不必重新读取文件。缺点:大多数编译器使用包含文件的路径来执行此操作,所以
#include "../include/foo.h"
#include "foo.h"
可能都引用同一个文件,但在某些编译器上仍会产生重复。
在 .h 文件的开头检查唯一预处理器符号的定义,如果未定义,则定义它
#ifndef PAILLIER_H
#define PAILLIER_H
在文件的最后
#endif // PAILLIER_H (comment is optional)
专业版:无论路径如何,都可以进行重复数据删除。缺点:如果你的 guard 名称不够独特,可能会导致问题(我参与过一个项目,有人在多个头文件中使用了“HEADER”)缺点:预处理器仍然必须读取整个头文件才能找到 #endif。
总结
您可能还想添加以下内容,使您的文件在包含 C 和 C++ 时都能正常工作
#ifdef __cplusplus
extern "C" {
#endif
// all your symbols etc here
#ifdef __cplusplus
}; // extern "C"
#endif
这将使您的头文件看起来像这样:
#ifndef PAILLIER_H
#define PAILLIER_H
#ifdef __cplusplus
extern "C" {
#endif
// original code here
...
// end original code
#ifdef __cplusplus
}; // extern "C"
#endif
#endif // PAILLIER_H
或
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// original code here
...
// end original code
#ifdef __cplusplus
}; // extern "C"
#endif
--- 编辑---
没有理由你不能同时使用两者
#pragma once
#ifndef MYPROJECT_SOMETHING_H
...
#endif
这样,如果 #pragma 由于路径原因使您失败,您仍然会被覆盖。
关于C++:如何在头文件中包含 Paillier.h,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30580629/
我有一个 C++ 类 key_gen,它有一些 paillier_prvkey_t 类型的数据成员。问题是我不能在我的头文件中包含 paillier 库(用 c 编写),比如 key_gen.h。但是
我正在尝试实现 this paper 中提出的协议(protocol)(第 3.2 节)。我最近开始研究同态加密和 Paillier。因此,我的问题可能太简单了,但我无法以任何方式解决问题。 论文说:
我正在尝试使用这个 Paillier 库 http://acsc.cs.utexas.edu/libpaillier/ ,它将只是我试图为 Mysql 服务器制作的一些 UDF 的一部分 这是我的 R
我是一名优秀的程序员,十分优秀!