gpt4 book ai didi

perl - 在 XS 中为 C 库注册多个 Perl 子引用

转载 作者:行者123 更新时间:2023-12-03 17:21:15 25 4
gpt4 key购买 nike

两个perlcall (在“存储回调上下文信息的策略”部分)和Extending and Embedding Perl (在“回调”部分)列出了 3 种不同的方式来处理从 XS/C 调用 Perl 子例程:

  • 立即:XS 电话
  • 延迟:将子引用保存为 SV* 以供以后使用
  • 多个:保存 n 个子引用以供以后使用

  • 上面 #3 列出的示例和详细信息使用 XS 中的哈希将 sub ref 与特定的 C 函数相关联,但它们预定义了固定数量的 C 函数,这是不够的。

    我正在开发一个 C 库的 XS 接口(interface),它使用带有可选参数的回调/函数指针,例如:
      blah(custom_type *o, void (*func) (void *data, int more_data), const void * data);

    这个库中的 C blah 最终将调用传递给它的函数以及传入的数据。

    如果可能的话,我想做一个 C API 到 Perl 的一对一映射。例如
      blah($o, \&func, $data);

    目前,我上面有#2,但是对 blah() 的另一个调用会覆盖保存的 SV *。

    我将如何实现上面的#3?

    最佳答案

    这是我想出的解决方案:

    此 C 库中的大多数回调将采用用户提供的 void * 并将其作为第一个参数传递。所以我将 SV * 和用户提供的数据保存在一个结构中:

    typedef struct __saved_callback {
    SV *func;
    void *data;
    } _saved_callback;

    我的 XS 函数将分配一个 _saved_callback 结构并将其作为第一个参数传递给 call_perl_sub() 以及 Perl 子引用和该用户假定的数据。
    void
    blah(obj, func, data)
    whatever *obj
    void *func
    void *data
    CODE:
    _saved_callback *sc = NULL;
    Newx(sc, 1, _saved_callback);
    sc->func = (SV *)func;
    sc->data = data;
    blah(obj, call_perl_sub, sc);

    然后调用 Perl 子引用(我省略了用户提供的数据参数的堆​​栈操作):
    void call_perl_sub(void *data) {
    dSP;
    int count;
    _saved_callback *perl_saved_cb = data;

    count = call_sv(perl_saved_cb->func, G_DISCARD);
    if ( count != 0 )
    croak("Expected 0 value got %d\n", count);
    }

    关于perl - 在 XS 中为 C 库注册多个 Perl 子引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1884584/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com