1

我对 Ubuntu Mate 中的 gcc 有一个奇怪的问题。

我需要编写一个使用第三方 C 库的 golang 程序,但我遇到了问题。

当我尝试在此代码中连接第三方库时:

package main

// #cgo CFLAGS: -I /opt/cprocsp/include/interfaces/
// #cgo CFLAGS: -I /opt/cprocsp/include/
// #cgo CFLAGS: -I /opt/cprocsp/include/cpcsp/
// #include <stddef.h>
// #include "wincspc.h"
// #include "wincspc_int.h"
import "C"

func main() {
  var CSPConfig C.CPC_CONFIG
  C.CPCGetDefaultConfig(&CSPConfig, nil)
  CSPConfig.logConfig.name = string(C.MODNAME)
}

我得到一个编译错误:

In file included from /opt/cprocsp/include/cpcsp/wincspc.h:28:0,
                 from ./gost.go:7:
/opt/cprocsp/include/cpcsp/WinCryptEx.h:35:10: fatal error: wincrypt.h: No such file or directory
 #include <wincrypt.h>
          ^~~~~~~~~~~~
compilation terminated.

我不知道这个错误是什么意思。接下来我决定打开 WinCryptEx.h 并在那里找到这些行:

#if defined UNIX || defined CSP_LITE
#include "CSP_WinCrypt.h"
#else // UNIX
#include <wincrypt.h>
#endif // UNIX

所以我意识到编译器运行 else 语句(但我希望它运行 if 语句,因为我的操作系统是 Linux)。为了确认问题,我决定编写一个 C 示例。

#if defined UNIX
#include "CSP_WinCrypt.h"
#else 
#include <wincrypt.h>
#endif 

int main()
{
    printf("Hello world");
}

当我尝试运行这个示例时,我得到了同样的错误。但后来我决定尝试运行下一个代码:

#if defined unix
#include "CSP_WinCrypt.h"
#else 
#include <wincrypt.h>
#endif 

int main()
{
    printf("Hello world");
}

它工作正常!编译器根据需要运行 if 语句。我不明白为什么。

我无法更改第三方库。所以我需要编译器与“UNIX”宏一起正常工作。

有没有人有办法解决吗?提前致谢。

4

1 回答 1

2

这个对流行的 Internet 搜索引擎的查询只带来了在适当的上下文中匹配单词“unix”的单个页面:它是系统特定宏上的这个页面

该页面暗示了两件事:

  • GCC 不保证UNIX定义了宏。

  • unix宏被描述为“常见”,但没有说明它必须存在的事实:

    但是,历史上特定于系统的宏的名称没有特殊前缀。例如,unix在 Unix 系统上定义是很常见的。对于所有此类宏,GCC 提供了一个并行宏,在开头和结尾添加了两个下划线。如果unix被定义,__unix__也会被定义。

在任何一种情况下,C 中的标识符都是区分大小写的,其预处理器处理的符号也是如此,因此unixUNIX是两个不相关的符号。

在你的情况下,我应该颠倒逻辑并测试 Windows,而不是相反。
在那里,符号_WIN32应该由 MinGW 和 MSVC 定义。

于 2020-05-31T18:40:04.823 回答