c – 外部“C”或不外部“C”[g vs cl]

我正在比较Numerical Recipes four1.c到Nayuki’s FFT.两者都是C版本,但我使用的是C驱动程序.为了进行比较,我正在使用CL.exe和g编译(或者更恰当地说,链接)到可执行文件中.两人似乎都在争论是否使用extern“C”作为four1功能,但似乎都不关心Nayuki的.我为four1制作了一个头文件,检查_WIN32是为了适当切换,它可以工作,但似乎是一个完全不可接受的黑客.我该如何解决这个问题?

这是头文件:

#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

这就是CL没有外部“C”的情况:

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

g很好用. CL不是.

>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);

到drvr.cpp文件,并删除头文件. CL仅在extern“C”存在时有效,但g则不然.除去外部“C”与g一起使用但不与CL一起使用.

是的,我知道原始的头文件是错的,这就是问题的关键.当我“正确地”做到这一点时它没有用,因此这个帖子.当我创建一个“不正确”的头文件来检查正在使用哪个编译器时,它工作正常,这是烦人的部分.只需检查c不起作用.

解决方法:

查看几乎所有系统C头文件,您将看到如下代码:

/* C++ needs to know that types and declarations are C, not C++.  */
#ifdef  __cplusplus
# define __BEGIN_DECLS  extern "C" {
# define __END_DECLS    }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif

__BEGIN_DECLS

// some declarations

__END_DECLS

这是您自己的标题中要遵循的模式,您需要在其中连接C和C.当然,除此之外,您不应使用前导下划线,因为它们是为系统内容保留的.

上一篇:ALV_TREE 一:cl_gui_alv_tree_simple


下一篇:python 调试器之pdb