在嵌入式 C 应用程序中从 Perl 调用 C 函数

发布于 2024-09-29 15:28:24 字数 474 浏览 3 评论 0原文

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

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

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

Application -(run)-> Perl

Application <-(function_x())- Perl

Application -(returnfunction_x)-> Perl

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

Ok, this is a very interesting question and there may not be any easy way to do this but figured I would throw this out there before deciding that modifying Perl is my underlying answer.

So I've got a C application that calls Perl scripts in an embedded fashion. This all works fine and dandy and it's pretty awesome that I can pass information in and get information back out. HOWEVER, now onto my next conquest; I need to allow my embedded script(s) to be able to call some functions within the C application that ORIGINALLY CALLED IT.

This is important because XSUB would require it to be an external library; but I don't want it to be an external library I want it to be a direct call to the C function(s). Now maybe this can be done via XSUB and I've just been reading and understanding it wrong.

Application -(run)-> Perl

Application <-(function_x())- Perl

Application -(returnfunction_x)-> Perl

The reason this cannot be an external library is because I am relying on data that is solely created/stored within the application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

错々过的事 2024-10-06 15:28:24

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 时,此类事情通常在传递给 parse_perl 的 xs_init 函数中完成。

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);

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

XSUBs actually don't require there to be an external library. They merely provide the ability to call to a c function from perl space, and provide some convenience in mapping the calling conventions between C and Perl.

All you need to do is register XSUBs you compiled into the embedding application with the perl interpreter you're embedding.

#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__);

When embedding perl, this sort of thing is usually done in the xs_init function you pass to 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);

After that you'll be able to call to the XSUB as Some::Perl::function from perl space, and that XSUB in turn is free to call back to your application in any way it wants to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文