混合 C 和 C++ 代码时未定义的符号
Undefined Symbol When Mixing C and C++ Code
我刚开始使用 nauty,它是用 C 语言编写的。Nauty 附带一个名为 geng 的程序,它可以生成图形文件,但也可以从您自己的程序中调用它,并使用图形一次一个。提供了一个示例 C 程序,我正在尝试将其转换为 C++。程序顶部的注释描述了一般方法。我已经在我的目标中列出了我的程序和来自 nauty 的源代码 geng.c。
这是我的代码
/* This is a sample of how to call geng as a procedure rather than
* running it as a separate process. The basic idea is to construct
* an argument list for geng's main() function. At compile time,
* assign a name to the macros OUTPROC and GENG_MAIN. A typical
* Unix-style compilation command would be:
gcc -o callgeng -O3 -DMAXN=32 -DOUTPROC=myoutproc -DGENG_MAIN=geng_main \
callgeng.c geng.c nauty.a
*/
extern "C" {
#include "gtools.h"
}
static unsigned long counter;
extern "C" void
OUTPROC(FILE *outfile, graph *g, int n)
{
/* This will be called for each graph. */
++counter;
}
int GENG_MAIN(int geng_argc, char* geng_argv[]);
int
main(int argc, char *argv[])
{
int geng_argc;
char *geng_argv[6];
// Set up geng argument list. The 0-th argument is the command name.
// There must be a NULL at the end. This example is for trees
// of order 16.
char argv0[] = "geng";
char argv1[] = "-q";
char argv2[] = "-cbf";
char argv3[] = "16";
char argv4[] = "15";
geng_argv[0] = argv0;
geng_argv[1] = argv1;
geng_argv[2] = argv2;
geng_argv[3] = argv3;
geng_argv[4] = argv4;
geng_argv[5] = NULL;
geng_argc = 5;
counter = 0;
GENG_MAIN(geng_argc,geng_argv);
printf("Number of graphs = %lu.\n",counter);
return 0;
}
程序 geng.c 包含行:
#ifdef GENG_MAIN
int
GENG_MAIN(int argc, char *argv[])
#else
int
main(int argc, char *argv[])
#endif
当我尝试构建项目时,它因链接器错误而失败:
Undefined symbols for architecture x86_64: "_geng_main", referenced
from:
_main in my_callgeng.o ld: symbol(s) not found for architecture x86_64
我尝试从命令行编译,它工作正常。
>gcc -o callgeng -O3 -DMAXN=32 -DOUTPROC=myoutproc -DGENG_MAIN=geng_main -I/Users/saul/nauty26r7 my_callgeng.cpp ~/nauty26r7/geng.c ~/nauty26r7/nauty.a
>./callgen
Number of graphs = 19320.
所以,这看起来像是一个 Xcode 问题。
在你的代码中(不是geng.c),你需要在前面加上extern "C"
整数
GENG_MAIN(int argc, char *argv[])
这样编译器就知道这个函数(来自 geng.c)必须在你的 C++ 中使用 C 链接而不是该函数的默认 C++ 链接(当你没有在充满 C++ 代码的文件中指定时你得到的) .
基本上,C++ 文件默认使用 C++ 函数链接,而 C 代码使用 C 链接函数,所以当您希望 C 代码能够从 C++ 代码中调用某些内容时(您的 GENG_MAIN) 您必须在 C++ 代码中指定 该特定函数必须使用 C 链接编译,即使它在内部是 C++。
这是一个 Xcode 错误。我没有意识到我必须在 BuildPhases/Compile Sources
下的每一行上放置编译器标志,所以我的代码只有“-DGENG_MAIN=geng_main”,而不是 geng.c.因此,在编译 geng.c 时没有发生替换,并且它必须编译 _main,而不是 _geng_main。
我刚开始使用 nauty,它是用 C 语言编写的。Nauty 附带一个名为 geng 的程序,它可以生成图形文件,但也可以从您自己的程序中调用它,并使用图形一次一个。提供了一个示例 C 程序,我正在尝试将其转换为 C++。程序顶部的注释描述了一般方法。我已经在我的目标中列出了我的程序和来自 nauty 的源代码 geng.c。
这是我的代码
/* This is a sample of how to call geng as a procedure rather than
* running it as a separate process. The basic idea is to construct
* an argument list for geng's main() function. At compile time,
* assign a name to the macros OUTPROC and GENG_MAIN. A typical
* Unix-style compilation command would be:
gcc -o callgeng -O3 -DMAXN=32 -DOUTPROC=myoutproc -DGENG_MAIN=geng_main \
callgeng.c geng.c nauty.a
*/
extern "C" {
#include "gtools.h"
}
static unsigned long counter;
extern "C" void
OUTPROC(FILE *outfile, graph *g, int n)
{
/* This will be called for each graph. */
++counter;
}
int GENG_MAIN(int geng_argc, char* geng_argv[]);
int
main(int argc, char *argv[])
{
int geng_argc;
char *geng_argv[6];
// Set up geng argument list. The 0-th argument is the command name.
// There must be a NULL at the end. This example is for trees
// of order 16.
char argv0[] = "geng";
char argv1[] = "-q";
char argv2[] = "-cbf";
char argv3[] = "16";
char argv4[] = "15";
geng_argv[0] = argv0;
geng_argv[1] = argv1;
geng_argv[2] = argv2;
geng_argv[3] = argv3;
geng_argv[4] = argv4;
geng_argv[5] = NULL;
geng_argc = 5;
counter = 0;
GENG_MAIN(geng_argc,geng_argv);
printf("Number of graphs = %lu.\n",counter);
return 0;
}
程序 geng.c 包含行:
#ifdef GENG_MAIN
int
GENG_MAIN(int argc, char *argv[])
#else
int
main(int argc, char *argv[])
#endif
当我尝试构建项目时,它因链接器错误而失败:
Undefined symbols for architecture x86_64: "_geng_main", referenced from: _main in my_callgeng.o ld: symbol(s) not found for architecture x86_64
我尝试从命令行编译,它工作正常。
>gcc -o callgeng -O3 -DMAXN=32 -DOUTPROC=myoutproc -DGENG_MAIN=geng_main -I/Users/saul/nauty26r7 my_callgeng.cpp ~/nauty26r7/geng.c ~/nauty26r7/nauty.a
>./callgen
Number of graphs = 19320.
所以,这看起来像是一个 Xcode 问题。
在你的代码中(不是geng.c),你需要在前面加上extern "C" 整数 GENG_MAIN(int argc, char *argv[]) 这样编译器就知道这个函数(来自 geng.c)必须在你的 C++ 中使用 C 链接而不是该函数的默认 C++ 链接(当你没有在充满 C++ 代码的文件中指定时你得到的) .
基本上,C++ 文件默认使用 C++ 函数链接,而 C 代码使用 C 链接函数,所以当您希望 C 代码能够从 C++ 代码中调用某些内容时(您的 GENG_MAIN) 您必须在 C++ 代码中指定 该特定函数必须使用 C 链接编译,即使它在内部是 C++。
这是一个 Xcode 错误。我没有意识到我必须在 BuildPhases/Compile Sources
下的每一行上放置编译器标志,所以我的代码只有“-DGENG_MAIN=geng_main”,而不是 geng.c.因此,在编译 geng.c 时没有发生替换,并且它必须编译 _main,而不是 _geng_main。