Рекомендуемый способ загрузки пакета .so в tcl статически или динамически - PullRequest
0 голосов
/ 17 сентября 2010

У меня есть исполняемый файл интерпретатора tcl и библиотека с расширением.Я хочу иметь возможность создавать библиотеку динамически (загружается с помощью Tcl load) или статически (один исполняемый файл, или загружается неявно).

Исполняемый код:

#ifdef GO_STATIC
    extern int My_ext_Init(Tcl_Interp* interp);
    Tcl_StaticPackage(interp, "my_ext", My_ext_Init, My_ext_Init);
    My_ext_Init(interp);  // THIS SHOULD NOT BE NEEDED !!
    Tcl_SetVariable(interp, "is_statically_linked", "1", TCL_GLOBAL_ONLY);
#else
    Tcl_SetVariable(interp, "is_statically_linked", "0", TCL_GLOBAL_ONLY);
#endif

Код библиотеки .. может быть статической или динамической библиотекой (.a или .so / .lib или .dll):

int My_ext_Init(Tcl_Interp *interp)
{
 if (Tcl_PkgProvide(interp, "My_ext", "1.0") == TCL_ERROR) {
  return TCL_ERROR;
 }
 Tcl_CreateObjCommand(interp, /*...etc...*/);

}

Код запуска tcl:

global is_statically_linked
if {$is_statically_linked} {
    load {} my_ext
} else {
    load my_ext my_ext
}

Проблема заключается в.. Я действительно не должен звонить My_ext_Init(interp);, как это должно вызывать Tcl, когда я оцениваю load {} my_ext

Сделал вики сообщества, чтобы рекомендованный путь можно было здесь поставить.

1 Ответ

0 голосов
/ 26 сентября 2010

Регистрация «статического пакета» выполняется в процедуре инициализации приложения и должна выполняться после создания основного интерпретатора (но, очевидно, до того, как вы запустите в нем свои скрипты).Это механизм, который действительно предназначен для работы с методом построения программы «Большое желание», когда вы используете Tcl_Main() для создания интерпретатора.Когда вы делаете это, в вашем коде есть обратный вызов (обычно называемый Tcl_AppInit, хотя имя на самом деле произвольно), который вы можете указать и который является идеальным местом для вызова Tcl_StaticPackage.Обратный вызов будет вызван в нужной точке, чтобы вы могли выполнить статическую регистрацию пакета.

Однако в наши дни это все считается довольно старой шляпой.Гораздо лучший метод - всегда использовать динамические библиотеки и вместо этого упаковать все вместе как starkit или starpack .Преимущество этого заключается в том, что вам просто нужно собрать файлы .so в виде пакетов с поддержкой заглушек (настоятельно рекомендуется в любом случае), а затем включить их в VFS во время процесса упаковки.После этого вы можете просто сделать package require, и все будет работать.(Или вы можете найти общие библиотеки в виртуальном монтировании при запуске и напрямую load.) Еще лучше то, что вы можете доставить один файл .kit, который поддерживает несколько платформ;Исполняемые файлы в Starpack не могут быть настолько гибкими, поскольку существуют некоторые естественные ограничения переносимости двоичных исполняемых файлов.: -)

...