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.afpc 所使用的链接工具和 gcc 的一样,是由 GNU Binutils 提供的 ld,而 clang 使用的链接工具是 LLVM 提供的 lld。不过 gcc 是可以链接 clang 编译的静态库的,也许可以手动使用 ar 命令将 clang 编译生成的 .o 文件封装成 .a 静态库。感兴趣的读者可以“亲自编译、亲自测试”一下。