我们可以通过将共享对象(即“*.so”文件)重命名为“$modulename-$version.tm”来创建模块吗?
Can we create module from shared object ie '*.so' files by renaming it to '$modulename-$version.tm'?
想要从共享对象文件 x.so
创建模块以避免 load
命令。共享对象 C 源代码 x.c
定义了包 p
,其中的版本为 1
。
我将 x.so
重命名为 p-1.tm
并将其路径添加到 ::tcl::tm::path
和
使用 package require p 1
显示无法读取命令的错误。这是因为主文件是 x.so
而不是 x.tcl
.
模块 始终 source
d。使它们包含一个可加载的库也需要一些技巧。这是一种方法。制作一个像这样的 Tcl 脚本:
apply {{scriptname realname} {
set script [open $scriptname]
chan configure $script -eofchar \x1a
chan read $script
chan configure $script -translation binary
chan seek $script 1 current; # Reset EOF state and skip past the EOF character
set f [file tempfile filename $realname.so]
chan copy $script $f
chan close $f
chan close $script
tailcall load $filename $realname; # Used to find the _Init function
}} [info script] YourRealLibraryName
将它与一个 ASCII EOF 字符 (Ctrl+Z) 连接起来,然后在最后连接你真正的共享库,将其全部保存为模块文件。当脚本被获取时,它会将库从自身末尾复制到一个临时文件中并从中加载它。
这取决于以下事实:source
始终将其用于读取脚本的通道配置为使用 EOF 字符充当 end-of-file 标记,即使在通常不会使用的系统上也是如此用它。然后您可以阅读过去并从那里提取您想要的任何有效负载数据。在最后连接一个可加载的库是微不足道的,但它需要在其他地方提取才能实际输入 load
。在内部,所有 Tcl 中动态库的加载都经过load
;这是唯一知道如何做的命令。我们只是为它做准备(默认情况下需要真实文件,因为我们将实际加载委托给执行该工作的操作系统库调用;file tempfile
非常适合这项工作!)。最后,我们将所有内容包裹在 apply
和 tailcall load
中,以便我们清理干净所有文件名操作机制。
使用虚拟文件系统的更复杂的方法是可能的,但需要更多的代码来解释。他们还在做这种事情,只是隐藏了更多的诡计。
想要从共享对象文件 x.so
创建模块以避免 load
命令。共享对象 C 源代码 x.c
定义了包 p
,其中的版本为 1
。
我将 x.so
重命名为 p-1.tm
并将其路径添加到 ::tcl::tm::path
和
使用 package require p 1
显示无法读取命令的错误。这是因为主文件是 x.so
而不是 x.tcl
.
模块 始终 source
d。使它们包含一个可加载的库也需要一些技巧。这是一种方法。制作一个像这样的 Tcl 脚本:
apply {{scriptname realname} {
set script [open $scriptname]
chan configure $script -eofchar \x1a
chan read $script
chan configure $script -translation binary
chan seek $script 1 current; # Reset EOF state and skip past the EOF character
set f [file tempfile filename $realname.so]
chan copy $script $f
chan close $f
chan close $script
tailcall load $filename $realname; # Used to find the _Init function
}} [info script] YourRealLibraryName
将它与一个 ASCII EOF 字符 (Ctrl+Z) 连接起来,然后在最后连接你真正的共享库,将其全部保存为模块文件。当脚本被获取时,它会将库从自身末尾复制到一个临时文件中并从中加载它。
这取决于以下事实:source
始终将其用于读取脚本的通道配置为使用 EOF 字符充当 end-of-file 标记,即使在通常不会使用的系统上也是如此用它。然后您可以阅读过去并从那里提取您想要的任何有效负载数据。在最后连接一个可加载的库是微不足道的,但它需要在其他地方提取才能实际输入 load
。在内部,所有 Tcl 中动态库的加载都经过load
;这是唯一知道如何做的命令。我们只是为它做准备(默认情况下需要真实文件,因为我们将实际加载委托给执行该工作的操作系统库调用;file tempfile
非常适合这项工作!)。最后,我们将所有内容包裹在 apply
和 tailcall load
中,以便我们清理干净所有文件名操作机制。
使用虚拟文件系统的更复杂的方法是可能的,但需要更多的代码来解释。他们还在做这种事情,只是隐藏了更多的诡计。