我有两个 Free Pascal 单元,我想在 Linux 上的 C 程序中使用它们。
这是我的做法:
$ fpc -fPIC base64.pas queueutils.pas
Warning: Only one source file supported
Free Pascal Compiler version 2.2.2 [2008/11/05] for x86_64
Copyright (c) 1993-2008 by Florian Klaempfl
Target OS: Linux for x86-64
Compiling queueutils.pas
queueutils.pas(2088,11) Warning: Symbol "Socket" is deprecated
queueutils.pas(2097,10) Warning: Symbol "Connect" is deprecated
queueutils.pas(2104,3) Warning: Symbol "Sock2Text" is deprecated
2432 lines compiled, 0.5 sec
4 warning(s) issued
$ ppumove -o queueutils -e ppl *.ppu
PPU-Mover Version 2.1.1
Copyright (c) 1998-2007 by the Free Pascal Development Team
Processing base64.ppu... Done.
Processing queueutils.ppu... Done.
Linking queueutils.o base64.o
Done.
到目前为止看起来还不错,libqueueutils.so 已创建:
$ file libqueueutils.so
libqueueutils.so: ELF 64-bit LSB shared object, AMD x86-64, version 1 (SYSV), not stripped
$ ldd libqueueutils.so
ldd: warning: you do not have execution permission for `./libqueueutils.so'
statically linked
然而,当 C 程序试图以这种方式使用库时:
libqueue = dlopen("./libqueueutils.so", RTLD_LAZY);
if (!libqueue) {
fprintf (stderr, "%s\n", dlerror());
}
它会产生一条错误消息:
$ ./tmbrkr
./libqueueutils.so: undefined symbol: VMT_PROCESS_TPROCESS
如果我将 process.o 和 process.ppu 添加到由 ppumove 完成的链接过程,这个与 VMT_PROCESS_TPROCESS 相关的错误就会得到解决。然而,在这样做之后,另一个单元丢失了,然后另一个单元......你明白了。
有没有办法以某种方式将所有必要的单元链接到一个 .so 文件中,以便 C 程序可以正确地 dlopen() 库?
最佳答案
就像普通二进制文件 (exe) 来自“程序”源文件一样,.so/dll 是从“库”源文件创建的。
其余的就是模型是一样的。您只需构建库主程序,编译器就会收集所有必要的单元并将它们填充到 .so 中。
使用 exports 关键字,您可以定义要导出的符号。
library testdll;
uses x,y,z;
// define exportable symbols here
// some examples of symbol exports
exports
P1 index 1, // dll based on index
P2 name 'Proc2', // normal export with alternate external symbol
P3, // just straight export.
P4 resident // for some MCU use
;
begin
// startup code
end.
另请参阅手册中的 $soname $libsuffix 和 $libprefix。
虽然我建议只使用最新的 2.6.0,而不是 5 年前的 2.2.2
虽然可能需要先用 PIC 重新编译 FPC。
关于static-linking - 链接 Free Pascal 程序以包含依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13561914/