我不确定问题的措辞是否正确,或者我想要的是否可能。
我有一个现有的 GCC 应用程序(如果重要的话,为 Cortex-M3 编译)。我想做的是创建一小部分可以调用现有应用程序的功能(只是一个方法,几个方法)。
我想将这几个方法放在特定的内存位置(我知道该怎么做)。我不知道该怎么做是让新应用程序与现有应用程序的对象进行编译/链接。
例如我现有的应用程序具有以下功能:
int Add(int a, int b);
新应用程序想要使用它:
int Calculate(int a, int b, int opType)
{
Add(a, b);
}
我可以访问所有链接器、obj、h 文件等。
您通常不能链接到可执行文件,只能链接到库(静态或共享)和目标文件。因此,我能给出的最好建议是将第一个程序的“核心”构建为共享库,并将“前端”(
main
)链接为针对核心共享库构建的可执行文件。然后,您的第二个程序也可以只是链接到共享库的程序。
您还可以在动态可执行文件上使用
dlopen
在运行时链接可执行文件,并使用 dlsym
获取所需功能的函数指针,尽管这通常仅在您无法控制第一个可执行文件时使用。
后者的示例(再次注意,这应该是最后的手段):
a.c:
#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();
}
感谢您的输入,但是通过使用现有应用程序中的 ELF 文件编译新应用程序,我能够准确地完成我想要的操作,通过指定
--just-symbols elffile.elf
如果您使用的是 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);
}
请注意,链接器无法知道您放在该位置的代码是否具有正确的原型,甚至是否存在 - 因此在链接时或运行时都不会进行错误检查。
您可能(取决于操作系统)还需要采取步骤来映射将函数放入本地进程地址空间的绝对内存位置。