我正在尝试编译一个可以集成到另一个代码中或直接执行(在链接后)的函数(不称为main)。
我试一试我的Mac,并且运作良好。 我终于在Linux(CentOS和ubuntu)上测试了它。但是,这项任务在Linux上看起来比预期的更难。
源代码如下(仅解释问题)
TEST.CPP:
#include <cstdio>
#ifdef __cplusplus
extern "C" {
#endif
int test(int argc, char const *argv[]);
#ifdef __cplusplus
}
#endif
int test(int argc, char const *argv[]) {
fprintf(stderr, "%s\n", "test");
return 0;
}
MacOS上的编译行
g++ -c test.cpp -o test.o && g++ test.o -o test -e _test
并在Linux上
g++ -c test.cpp -o test.o && g++ test.o -o test -e test
我尝试使用clang,g ++和Intel编译器对我的MacOS进行测试,所有3种工作正常。
我在Linux上尝试使用g ++和英特尔编译器,总是出现同样的错误。
usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
关于我做错了什么或遗失的任何建议,解释或解决方案都会非常有帮助。 感谢
编辑:
目前,我有一个&#34;定义&#34;创建一个main,但如果我们有很多函数,我们每次都有义务做两个编译(一个用于函数版本,一个用于执行),最后使代码更重。
就像本主题中讨论的那样is there a GCC compiler/linker option to change the name of main?
要做一个从我想要收集的一堆小程序继承的XY,它更容易使用(用于远程执行......)。但是,如果需要,每个人都需要能够独立执行,以便进行调试......我在使用&#34; execv&#34;之间犹豫不决。并将每个main转换为函数。我可能选错了。
编辑: 最终目标是能够拥有独立的计划。但我们也可以从外部软件调用。
解决方案: 解决方案看起来是通过dlopen调用主要的
答案 0 :(得分:4)
你不能这样做(即使它似乎适用于MacOSX,它是特定于实现的undefined behavior)。
Linux crt0正在做的事情比你想象的要复杂得多。
C标准(例如C11的n1570)需要main
函数用于托管实现(第5.1.2.2.1节):
程序启动时调用的函数名为
main
。该实现声明此函数没有原型。
并且C ++标准也requires a main
并强烈要求在 main
运行之前完成以及之后>构建静态数据em>它已经返回(并且各种crt0技巧正在Linux上实现该功能)。
如果你想了解血腥细节(并且它们并不容易!),请研究crt0实现的ABI和(自由软件)源代码。
我正在尝试编译一个可以集成到另一个代码中的函数(不称为main)
顺便说一句,要动态使用其他程序中的某些代码(例如plug-ins),请考虑使用dynamic linker。我建议在dlopen(3)共享库上使用符合POSIX的dlsym(3)和position-independent code。它适用于大多数Unix风格(包括MacOSX&amp; Linux&amp; Solaris&amp; AIX)。对于C ++代码,请注意name mangling,因此请至少阅读C++ dlopen mini howto。
库有问题,无法执行,没有?
我不明白这意味着什么。你当然可以加载一个插件,然后在主程序dlopen
中运行代码。
(在Linux上,像libc.so
这样的某些库甚至是专门用来作为可执行文件工作的;我不推荐这种做法用于你自己的代码)
您可能需要几天才能阅读Drepper的How To Write Shared Libraries(但它是高级内容)。
如果您想在运行时添加一些代码,请另请阅读this answer和that one。
最终目标是能够拥有独立的计划。但我们也可以从外部软件调用
你不能这样做(这没有任何意义)。但是,您可以使用processes等inter-process communication和其他许多程序与其他正在运行的程序(即pipe(7))进行通信。首先在编码之前阅读Advanced Linux Programming。另请阅读Operating Systems : Three Easy Pieces
解决方案看起来是通过dlopen来调用main
通过main
&amp;拨打dlopen
功能C ++标准禁止使用dlsym
(禁止使用指向main
的指针)。 main
函数具有非常特定的状态和角色(并且是专门编译的;编译器知道main
)。
(也许调用main
获得dlsym
似乎可以在某些Linux系统上运行,但它肯定是未定义的行为,所以你不应该这样做)