我正在比较Numerical Recipes four1.c和Nayuki's FFT。两个都是C版本,但我正在使用C++驱动程序。为了进行比较,我将它们都编译(或更确切地说,链接)成一个可执行文件,使用CL.exe和g++。它们似乎在争夺是否应该对four1函数使用extern“C”,但都不关心Nayuki的问题。我为four1制作了一个头文件,检查_WIN32以适当地进行切换,这有效,但似乎是完全不可接受的黑客行为。我该如何解决这个问题?
这是头文件:
CL可行的代码对g++来说可能不适用,g++适用的代码也可能在CL中无法运行。至少就这个文件而言是如此。Nayuki代码不存在这样的问题。
我尝试按建议修改了头文件,现在dfour1.h如下:
将文件从drvr.cpp文件中删除。只有在
是的,我知道原始头文件是错误的,这就是问题的关键。当我以“正确”的方式操作时,它不起作用,因此发布了帖子。当我制作一个“不正确”的头文件来检查正在使用的编译器时,它起作用了,这很让人烦恼。简单地检查c ++无法解决问题。
这是头文件:
#pragma once
#ifdef _WIN32
extern "C" void four1(float data[], unsigned long nn, int isign);
#else
void four1(float data[], unsigned long nn, int isign);
#endif
这是没有使用extern "C"的CL的操作:
drvr.obj : error LNK2019: unresolved external symbol "void __cdecl four1(float * const,unsigned long,int)" (?four1@@YAXQAMKH@Z) referenced in function _main
drvr.exe : fatal error LNK1120: 1 unresolved externals
如果使用extern "C",则g++会执行以下操作:
/tmp/ccK1Hb2N.o: In function `main':
drvr.cpp:(.text+0x347): undefined reference to `four1'
collect2: error: ld returned 1 exit status
CL可行的代码对g++来说可能不适用,g++适用的代码也可能在CL中无法运行。至少就这个文件而言是如此。Nayuki代码不存在这样的问题。
我尝试按建议修改了头文件,现在dfour1.h如下:
#pragma once
/* C++ needs to know that types and declarations are C, not C++. */
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
void dfour1(double data[], unsigned long nn, int isign);
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif
可以正常编译,而则不行。>cl drvr.cpp dfour1.c fft.c carrier.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
drvr.cpp
Generating Code...
Compiling...
dfour1.c
fft.c
Generating Code...
Compiling...
carrier.cpp
Generating Code...
Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:drvr.exe
drvr.obj
dfour1.obj
fft.obj
carrier.obj
drvr.obj : error LNK2019: unresolved external symbol "void __cdecl dfour1(double * const,unsigned long,int)" (?dfour1@@YAXQANKH@Z) referenced in function _main
drvr.exe : fatal error LNK1120: 1 unresolved externals
顺便说一下,如果没有头文件,我只需要添加以下内容也会发生同样的情况:
extern "C" void dfour1(double data[], unsigned long nn, int isign);
将
extern "C"
存在时,CL才起作用,但是g++不起作用。而删除extern "C"
可以与g++一起使用,但不能与CL一起使用。是的,我知道原始头文件是错误的,这就是问题的关键。当我以“正确”的方式操作时,它不起作用,因此发布了帖子。当我制作一个“不正确”的头文件来检查正在使用的编译器时,它起作用了,这很让人烦恼。简单地检查c ++无法解决问题。
__cplusplus
而不是其他。 - Some programmer dudeexterm "C"
用于当您想要展示与 C 兼容的接口、C 调用约定和没有 C++ 名称修饰时 - 这显然会限制您可以在接口中公开的内容(例如,没有 C++ 标准库类型、无法重载等)。如果这正是您需要或想要的,那么就使用它;否则就不要使用。就这么简单。 - Jesper Juhl