我正在尝试编译一个可以集成到另一个代码中或直接执行(链接后)的函数(不称为 main)。
我在我的 Mac 上尝试了一下,效果很好。 我最终在Linux(CentOS和ubuntu)上测试了它。然而,正如预期的那样,该任务在 Linux 上看起来更困难。
源码如下(只是为了说明问题)
测试.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
我在我的 MacOS 上尝试使用 clang、g++ 和 Intel 编译器,这 3 个编译器都工作正常。
我在 Linux 上尝试使用 g++ 和 Intel 编译器,总是出现同样的错误。
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
任何关于我做错或遗漏的建议、解释或解决方案都会非常有帮助。 谢谢
编辑:
目前,我有一个“定义”来创建一个 main,但如果我们有很多函数,我们有义务每次进行两次编译(一次用于函数版本,一次用于执行),最终使代码变得更重。
就像本主题中讨论的那样 is there a GCC compiler/linker option to change the name of main?
为了不做 XY,我继承了一堆我想要收集的小程序,这样它更容易使用(用于远程执行......)。然而,如果需要的话,每个函数都需要能够独立执行,以便进行调试……我在使用“execv”和将每个 main 转换为函数之间犹豫不决。我可能会做出错误的选择。
编辑: 最终的目标是能够拥有独立的节目。但我们也可以从外部软件调用。
解决方案: 解决方案看起来是通过 dlopen 调用 main
最佳答案
你不能这样做(即使它看起来可以在 MacOSX 上运行,它也是特定于实现的 undefined behavior )。
Linux crt0正在做比你想象的更复杂的事情。
C 标准(例如 C11 的 n1570)需要用于托管实现的 main
函数 (§5.1.2.2.1):
The function called at program startup is named
main
. The implementation declares no prototype for this function.
C++ 标准也是 requires a main
并且强烈要求在 main
运行之前和之后返回一些处理(例如静态数据的构造)(各种 crt0 技巧正在 Linux 上实现该功能)。
如果您想了解血淋淋的细节(而且它们并不容易!),请研究ABI以及 crt0 实现的(免费软件)源代码。
I am trying to compile a function (not called main) that can be integrated in another code
顺便说一句,要动态使用另一个程序中的某些代码(例如 plug-ins ),请考虑使用 dynamic linker 。我建议使用符合 POSIX 标准的 dlopen(3)与 dlsym(3)上position-independent code共享库。它适用于大多数 Unix 版本(包括 MacOSX & Linux & Solaris & AIX)。对于 C++ 代码,请注意 name mangling所以至少阅读C++ dlopen mini howto .
另请阅读 Program Library HowTo .
Problems with libraries, they cannot be executed, no ?
我不明白这是什么意思。您当然可以加载一个插件,然后从主程序 dlopen
运行它内部的代码。
(在 Linux 上,一些库(例如 libc.so
)甚至是专门构建的,也可作为可执行文件使用;我不建议您自己的代码采用这种做法)
您可能需要几天时间才能阅读 Drepper 的 How To Write Shared Libraries (但这是高级的东西)。
<小时/>如果您想在运行时添加一些代码,另请阅读 this answer和 that one .
The final goal is to be able to have independent program. But that we can call from an external software too
你不能这样做(而且没有意义)。但是,您可以使用 processes 与其他正在运行的程序(即 inter-process communication )进行通信。如pipe(7) -s 和许多其他。阅读 Advanced Linux Programming首先和编码之前。另请阅读Operating Systems : Three Easy Pieces
The solution looks to be, to a call to the main through a dlopen
C++ 标准禁止通过 dlopen
和 dlsym
调用 main
函数(该标准不允许使用指向 main
的指针)。 main
函数具有非常具体的地位和作用(并且是专门编译的;编译器知道 main
)。
(也许调用由 dlsym
获得的 main
似乎可以在某些 Linux 系统上工作,但这肯定是未定义的行为,因此您不应该这样做)
关于c++ - "no main"C++ 中用于链接或执行的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45440506/