gpt4 book ai didi

C++:如何在头文件中包含 Paillier.h

转载 作者:行者123 更新时间:2023-11-28 02:26:13 27 4
gpt4 key购买 nike

我有一个 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 文件中,您需要防止这种重复。有两种常见的方法可以做到这一点。

  1. 编译指示

在 .h 文件的开头使用预处理器指令 #pragma,GNU C 和 C++ 编译器都能理解:

#pragma once

优点:预处理器检测到 #include 语句中的重复项,因此不必重新读取文件。缺点:大多数编译器使用包含文件的路径来执行此操作,所以

#include "../include/foo.h"
#include "foo.h"

可能都引用同一个文件,但在某些编译器上仍会产生重复。

  1. #ifndef 守卫

在 .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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com