静态链接插件

生成可执行文件

而不是跑 ob_client 我们可以构建一个可执行脚本。该命令适用于所有平台:

flx --static -c -od . ob_client.flx

这将把一个可执行文件 ob_client 在Linux或OSX上的当前目录中,或 ob_client.exe 在Windows上。

您可以运行可执行文件:

./ob_client

它将像以前一样工作,动态加载插件。有希望地。但是可执行文件不是自包含的,所以不容易被传送,插件二进制文件也必须被传送,并放在动态链接器搜索路径上。

静态预链接插件

有解决办法!当Felix试图通过其文本名加载插件时,它首先查看一个名为 预备役 看看它是否是预装的。否则,它将尝试实际的操作系统级库加载。如果我们想把这个程序静态地链接到存储库中,那么我们就可以避免把这个程序静态地链接起来。

为此,我们必须首先为插件创建一个对象文件,而不是DLL。

flx --static -c -od . --nolink ob_implementation.flx

这会将对象文件放入当前目录中。它将被称为 ob_implementation_static.o 在MacOSX或Linux上,或 ob_implementation_static.obj 在Windows上。

现在我们也必须将程序编译为目标文件:

flx --static -c -od . --nolink ob_client.flx

现在我们需要一个名为 静态装载机重击

// ob.flx
open Dynlink;

static-link-plugin ob_implementation;

static-link-symbol ob_client_create_thread_frame in plugin ob_client;
static-link-symbol ob_client_flx_start in plugin ob_client;

val linstance =  Dynlink::prepare_lib("ob_client");
C_hack::ignore(linstance);

这实际上是我们现在的主线!我们需要开课 Dynlink 查找用于在注册表中存储内容的函数。

接下来,我们指定插件的名称。

我们还需要指定用于运行程序的两个符号的名称。 ob_client_create_thread_frame 分配全局存储对象。 ob_client_flx_start 运行该对象的初始化过程:这实际上是您以前错误地认为的程序。

什么??是的,没错。Felix不做程序,只做类库。你认为你的程序实际上是库初始化过程的副作用。

最后,我们创建一个库的实例 ob_client 用Dylink的功能 prepare_lib . 这将创建线程框架对象并初始化它(是的,这是您正在运行的“程序”)。

既然这就是我们想要做的,我们只要忽略库句柄,我们就完成了。

ob_client 代码运行时,它会尝试加载插件 ob_implementation . 但是它会在注册表中找到它,以及插件的标准符号。这个 static-link-plugin 语句生成更新存储库的代码。

以下是如何链接程序:

flx --static -c -od . \
  ob_implementation_static.o \
  ob_client_static.o \
  ob.flx

注意,不幸的是,您必须给出对象文件的依赖于平台的名称。注意,Felix还添加了后缀 _static to object files compiled for static linkage. Object files compiled for dynamic linkage get the suffix _ 而是动态的。在某些平台上,它们是相同的,但不是Linux。动态链接对象是用 `-fPIC 位置独立代码。静态文件不是链接。对于x86_64处理器,省略-fPIC会生成更快的函数调用。

最终程序的运行方式如下:

./ob