2012-09-26 116 views
0

我不确定问题是否正确表达,或者我想要什么是可能的。如何动态链接GCC对象?

我有一个现有的GCC应用程序(如果重要的话,为Cortex-M3编译)。我想要做的是创建一小段可以调用到现有应用程序中的功能(只有一种方法,几种方法)。我想将这几个方法放在特定的内存位置(我知道如何做到这一点)。我不知道该怎么做是让新应用程序编译/链接到现有应用程序的对象。

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

int Add(int a, int b); 

和新应用程序要使用它:

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

我可以访问所有连接,OBJ,H文件等。

+0

不知道理解有一个输入到链接你试图达到的目标......你当然可以在建立你的应用程序时与静态或共享库链接。你想链接一些共享库或运行时?如果是这样,请查看'dl'函数(dlopen,dlsym等)......或者只是澄清问题...... – Macmade

+0

您的Cortex-M3运行的是什么系统?如果它是一个自定义操作系统或一个小型RTOS,那么很有可能必须实现自己的动态链接/加载功能。根据您的需要,它可能非常简单(如果您只需加载位于固定地址且已链接到位于这些地址的项目),或者如果您需要处理地址修正,它可能会更复杂。 –

回答

1

感谢您的输入,但是我能够做什么,我想通过编译使用ELF文件从现有的应用程序中的新的应用程序通过指定
--just-symbols elffile.elf

4

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

您也可以使用dlopen动态可执行文件的可执行文件在运行时链接,并使用dlsym获取函数指针所需的功能,虽然这通常只使用,如果你有过第一个可执行的控制。

后者的示例(再次指出,这应该是最后的手段):

交流:

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

BC:

#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(); 
} 
+0

我不知道我明白。为什么选择使用'dlsym'是最后的选择? – sherrellbc

+0

你通常不应该是'dlopen'可执行文件。一个合适的可重用代码库将作为库被运送,而不是可执行文件。如果你被迫链接到一个可执行文件,这表明你可能想重新考虑你的设计。 – nneonneo

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); 
} 

注意链接器无法知道,如果你已经在那个位置把代码有办法正确的原型,甚至存在 - 所以在链接时或运行时都没有错误检查。

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