Free Pascal 链接 C/C++ 静态库
本文提供的方法仅在 Windows 中测试通过,未在 Linux 中进行过测试,但理论上也能使用。
Free Pascal 中可以用非常简单的代码链接到动态库:
pascalfunction MyAdd(x, y: Integer): Integer; external 'mylib.dll' name 'MyAdd';
另外也可以链接到静态库,这样分发程序的时候就不用带上一堆 DLL 文件了。
首先将 C 代码编译为静态库,然后在 Lazarus > 项目选项 > 编译器选项 > 路径 > 库 (-Fl) 中输入静态库存放的路径。此处以 C 编写的静态库导出 MyAdd()
函数为例,演示如何在 Free Pascal 中调用它。
C 代码如下:
cextern int MyAdd(int x, int y)
{
return x + y;
}
使用 gcc 编译后生成的静态库文件名为 libmylib.a(也可以使用 MSVC 编译,但编译后的静态库需要额外处理,后文会提到)。
Pascal 链接和调用静态库的代码如下:
pascalprogram main;
{$LINKLIB 'mylib'}
function MyAdd(x, y: Integer): Integer; cdecl; external;
begin
WriteLn(Format('123 + 456 = %d', [MyAdd(123, 456)]));
end.
需要注意以下问题:
- 静态库的扩展名必须是 .a 。如果是其他扩展名,fpc 会将其视作 DLL 动态链接库,导致链接失败;
- 若静态库文件名为 libxyz.a,链接时可写作
{$LINKLIB xyz}
,能省略 lib 前缀和 .a 扩展名; - fpc 可支持 gcc 编译器生成的静态库;
- 如果是 MSVC 编译的静态库,需要使用
ranlib
命令(包含于 WinLibs)转格式; - fpc 不支持 clang 编译器生成的静态库,似乎是 COFF 格式有问题。
假设 MSVC 编译的静态库文件名为 mylib.lib,处理命令如下:
powershellranlib mylib.lib
mv mylib.lib libmylib.a
fpc 所使用的链接工具和 gcc 的一样,是由 GNU Binutils 提供的 ld
,而 clang 使用的链接工具是 LLVM 提供的 lld
。不过 gcc 是可以链接 clang 编译的静态库的,也许可以手动使用 ar
命令将 clang 编译生成的 .o 文件封装成 .a 静态库。感兴趣的读者可以“亲自编译、亲自测试”一下。