12

好的,这是一个非常有趣的问题,可能没有任何简单的方法可以做到这一点,但我想我会在决定修改 Perl 是我的基本答案之前把它扔掉。

所以我有一个以嵌入式方式调用 Perl 脚本的 C 应用程序。这一切都工作得很好而且很漂亮,而且我可以传递信息并取回信息真是太棒了。但是,现在开始我的下一个征服;我需要允许我的嵌入式脚本能够调用最初调用它的 C 应用程序中的一些函数。

这很重要,因为 XSUB 要求它是一个外部库;但我不希望它成为一个外部库,我希望它是对 C 函数的直接调用。现在也许这可以通过 XSUB 完成,但我一直在阅读和理解错误。

Application -(run)-> Perl

Application <-(function_x())- Perl

Application -(returnfunction_x)-> Perl

这不能是外部库的原因是因为我依赖于仅在应用程序中创建/存储的数据。

4

1 回答 1

7

XSUB 实际上不需要外部库。它们仅提供从 perl 空间调用 ac 函数的能力,并为映射 C 和 Perl 之间的调用约定提供了一些便利。

您需要做的就是使用您正在嵌入的 perl 解释器注册您编译到嵌入应用程序中的 XSUB。

#include "XSUB.h"

XS(XS_some_func);
XS(XS_some_func)
{
    dXSARGS;
    char *str_from_perl, *str_from_c;

    /* get SV*s from the stack usign ST(x) and friends, do stuff to them */
    str_from_perl = SvPV_nolen(ST(0));

    /* do your c thing calling back to your application, or whatever */
    str_from_c = some_c_func(str_from_perl);

    /* pack up the c retval into an sv again and return it on the stack */
    mXPUSHp(c_str);
    XSRETURN(1);
}

/* register the above XSUB with the perl interpreter after creating it */
newXS("Some::Perl::function", XS_some_func, __FILE__);

当嵌入 perl 时,这种事情通常在你传递给的 xs_init 函数中完成parse_perl

EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);

static void
xs_init (pTHX)
{
    newXS("Some::Perl::function", XS_some_func, __FILE__);
    /* possibly also boot DynaLoader and friends. perlembed has more
     * details on this, and ExtUtils::Embed helps as well. */
    newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
}

perl_parse(my_perl, xs_init, argc, my_argv, NULL);

之后,您将能够Some::Perl::function从 perl 空间调用 XSUB,而 XSUB 又可以自由地以任何它想要的方式回调到您的应用程序。

于 2010-10-29T02:43:40.780 回答