"没有主要"用于在C ++中链接或执行的函数

时间:2017-08-01 14:24:06

标签: c++ linux macos compilation

我正在尝试编译一个可以集成到另一个代码中或直接执行(在链接后)的函数(不称为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调用主要的

1 个答案:

答案 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

另请阅读Program Library HowTo

  

库有问题,无法执行,没有?

我不明白这意味着什么。你当然可以加载一个插件,然后在主程序dlopen中运行代码。

(在Linux上,像libc.so这样的某些库甚至是专门用来作为可执行文件工作的;我不推荐这种做法用于你自己的代码)

您可能需要几天才能阅读Drepper的How To Write Shared Libraries(但它是高级内容)。

如果您想在运行时添加一些代码,请另请阅读this answerthat one

  

最终目标是能够拥有独立的计划。但我们也可以从外部软件调用

你不能这样做(这没有任何意义)。但是,您可以使用processesinter-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系统上运行,但它肯定是未定义的行为,所以你不应该这样做)