用于导入的 dynlib 编译指示

使用 dynlib 编译指示从动态库(Windows 上的 .dll 文件, UNIX 上的 lib*.so 文件)中导入过程或变量。 必须把动态库的名称写在参数里:

  1. proc gtk_image_new(): PGtkWidget
  2. {.cdecl, dynlib: "libgtk-x11-2.0.so", importc.}

一般来说,导入动态库不需要任何特殊链接选项或与导入库链接。这也意味着不需要安装 devel 软件包。

dynlib 导入机制支持版本化:

  1. proc Tcl_Eval(interp: pTcl_Interp, script: cstring): int {.cdecl,
  2. importc, dynlib: "libtcl(|8.5|8.4|8.3).so.(1|0)".}

在运行时,将按以下顺序搜索动态库:

  1. libtcl.so.1
  2. libtcl.so.0
  3. libtcl8.5.so.1
  4. libtcl8.5.so.0
  5. libtcl8.4.so.1
  6. libtcl8.4.so.0
  7. libtcl8.3.so.1
  8. libtcl8.3.so.0

dynlib 指示不仅支持常量字符串作为参数,还支持一般的字符串表达式:

  1. import std/os
  2. proc getDllName: string =
  3. result = "mylib.dll"
  4. if fileExists(result): return
  5. result = "mylib2.dll"
  6. if fileExists(result): return
  7. quit("无法加载动态库")
  8. proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}

注意: 类似 libtcl(|8.5|8.4).so 的形式只支持常量字符串,因为它们是预编译的。

注意: 由于初始化顺序的问题,向 dynlib 编译指示传递变量将在运行时出错。

注意: dynlib 导入,可以通过 --dynlibOverride:name 命令行选项进行覆盖,参阅编译器用户指南]。