我们是否可以通过将共享对象(即“ * .so”文件)重命名为“ $ modulename- $ version.tm”来创建模块?

时间:2019-06-20 14:50:53

标签: tcl

要从共享对象文件x.so创建模块,以避免使用load命令。共享库C源代码x.c定义了版本为p的软件包1

我将x.so重命名为p-1.tm,并在::tcl::tm::path中添加了它的路径, 已使用package require p 1

它显示无法读取命令的错误。这是因为主文件是x.so而不是x.tcl

1 个答案:

答案 0 :(得分:2)

模块总是 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字符充当文件结尾标记,即使在通常不使用它的系统上也是如此。然后,您可以阅读过去的内容,然后从中提取所需的任何有效负载数据。最后将一个可加载的库连接起来很简单,但是需要将其提取到其他位置才能实际输入到load中。在内部,在Tcl中 all 个动态库的加载都是通过load进行的;这是唯一知道该怎么做的命令。我们正在为此做准备(默认情况下,实际文件是必需的,因为我们将实际加载委托给完成该工作的操作系统库调用; file tempfile非常适合此工作!)。最后,我们将所有内容最后包装在applytailcall load中,以便我们清理干净地清理掉所有文件名处理机制。

使用虚拟文件系统的更复杂的方法是可能的,但是需要更多的代码来解释。他们仍然在做这种事情,但是看不到更多的诡计。