如何动态链接GCC对象?

时间:2012-09-26 20:26:40

标签: c++ c gcc compiler-construction linker

我不确定问题是否正确,或者我想要的是什么。

我有一个现有的GCC应用程序(如果重要的话,为Cortex-M3编译)。我想要做的是创建一个可以调用现有应用程序的一小部分功能(只需一个方法,几个方法)。

我想将这些方法放在特定的内存位置(我知道该怎么做)。我不知道该怎么做是让新的应用程序编译/链接现有应用程序的对象。

例如,我现有的应用程序具有以下功能:

int Add(int a, int b);

新应用程序想要使用它:

int Calculate(int a, int b, int opType)
{
  Add(a, b);
}

我可以访问所有链接器,obj,h文件等。

3 个答案:

答案 0 :(得分:4)

您通常无法链接到可执行文件,只能链接到库(静态或共享)和目标文件。因此,我能给出的最好的建议是将第一个程序的“核心”构建为共享库,并将“前端”(main)链接为针对核心共享库构建的可执行文件。然后,您的第二个程序也可以只是一个链接到共享库的程序。

您还可以在动态可执行文件上使用dlopen在运行时链接可执行文件,并使用dlsym获取所需功能的函数指针,但这通常仅在您无法控制时使用第一个可执行文件。

后者的例子(再次注意这应该是最后的手段):

交流转换器:

#include <stdio.h>
int main() { printf("hello world!\n"); return 42; }

b.c:

#include <stdio.h>
#include <dlfcn.h>

main() {
    void *handle = dlopen("a", RTLD_LAZY);
    if(!handle) {
        printf("failed: %s\n", dlerror());
        return -1;
    }
    int (*amain)() = dlsym(handle, "main");
    if(!amain) {
        printf("dlsym failed: %s\n", dlerror());
        return -1;
    }
    return amain();
}

答案 1 :(得分:1)

感谢您的输入,但是我能够通过使用现有应用程序中的ELF文件编译新应用程序来完全按照我想要的方式执行操作,并通过指定来输入链接器 --just-symbols elffile.elf

答案 2 :(得分:0)

如果您使用的是linux变体,那么@nneonneo给出的使用dlopen()和dlsym()的答案是最好的方法。

但是,假设您正在使用另一个操作系统(或根本没有操作系统)和/或您确实需要此代码存放在固定位置(例如,如果您需要将执行转移到特定内存上的地址)设备,例如,如果进行闪存操作),您可以使用硬编码函数指针。

声明一个函数指针,如下所示:


typedef int (*AddFnPtr)(int a, int b);
AddFnPtr MyAddFunction = (AddFnPtr)ADDRESS_OF_YOUR_FUNCTION;

然后打电话给:


int Calculate(int a, int b, int opType)
{
  MyAddFunction(a, b);
}

请注意,链接器无法知道您放置在该位置的代码是否具有正确的原型,甚至是否存在 - 因此在链接时或运行时都没有错误检查。

您可能(取决于操作系统)还需要采取措施来映射您将函数放入本地进程地址空间的绝对内存位置。