构建插件

下面是构建和使用插件的具体说明。

接口文件

首先我们有一份档案 ob_interface.flx 在当前目录中:

// ob_interface.flx
interface ob_t  {
  name: 1->string;
  underage: 1->bool;
  setage: int -> 0;
};

实施文件

现在我们在 ob_implementation.flx 在当前目录中:

// ob_implementation.flx
include "./ob_interface";

object ob (x:string) implements ob_t {
  var age = 0;
  method fun name () => x;
  method fun underage () => age < 21;
  method proc setage (y:int) { age = y; }
};

fun setup(x:string) {
  println$ "Setup string `" + x + "`";
  return 0;
}

export fun setup of string as "ob_implementation_setup";
export fun ob of string as "ob_implementation";

这里 include 指令正在加载与包含文件相关的接口。为了方便起见,请将两者都放在当前目录中!

这个 export fun 指令生成 extern "C" 一个Felix函数的包装器,为其提供带引号的链接器名称。由于重载,您必须指定函数域类型才能选择正确的函数(即使只有一个函数)。

客户端文件

我们的插件客户端就是这个文件 ob_client.flx 在当前目录中:

// ob_client.flx
include "./ob_interface";

var ob =
  Dynlink::load-plugin-func1
    [ob_t,string]
    ( dll-name="ob_implementation", setup-str="", entry-point="ob")
;
var joe = ob "joe";
println$ "name " + joe.name();

这将加载插件,使用setup函数初始化它,然后运行主入口点。

构建插件

该插件使用命令行在所有平台上构建:

flx -c -od . ob_implementation.flx

这个 -c 告诉Felix编译并链接文件,但不运行它。这个 -od . 告诉Felix将链接器输出放在当前目录中。文件将具有基名 ob_implementation 在所有平台上,并且将具有与平台上的DLL相匹配的扩展名。

运行客户端

要在OSX上运行客户端,我只需执行以下操作:

flx ob_client.flx

就这样!您可能需要设置控制DLL搜索路径的环境变量。在OSX上:

DYLD_LIBRARY_PATH=. flx ob_client.flx

Linux上:

LD_LIBRARY_PATH=. flx ob_client.flx

在Windows上:

PATH=. flx ob_client.flx

结果

结果应该是控制台上的以下输出:

Setup string ``
name joe

调试

如果设置环境变量 FLX_SHELL_ECHO=1 然后系统Shell的所有调用都将回显到控制台。此外,将报告对系统动态加载程序的调用以加载插件。