标签: xs

阻止Perl XS模块无声地回退到纯perl

似乎CPAN上的一些(很多?)模块部分使用XS在C中实现,并且如果需要可以回退到纯perl实现.虽然这很聪明,但它显然会损害性能,我想知道它发生了所以我可以解决问题.

是否有停止或检测此类后备的一般方法?

有关此行为的示例,请查看(非常方便)Date :: Simple(代码段)

perl cpan module perl-module xs

6
推荐指数
2
解决办法
293
查看次数

在XS中创建线程回调

编辑:我已经为此创建了一张票,其中有关于这种做法的替代方案的数据.

我已经更新了代码,试图使用MY_CXT的回调,因为gcxt没有跨线程存储.然而,这个段错误在ENTER.

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#ifndef aTHX_
#define aTHX_
#endif

#ifdef USE_THREADS
#define HAVE_TLS_CONTEXT
#endif

/* For windows  */
#ifndef SDL_PERL_DEFINES_H
#define SDL_PERL_DEFINES_H

#ifdef HAVE_TLS_CONTEXT
PerlInterpreter *parent_perl = NULL;
extern PerlInterpreter *parent_perl;
#define GET_TLS_CONTEXT parent_perl =  PERL_GET_CONTEXT;
#define ENTER_TLS_CONTEXT \
        PerlInterpreter *current_perl = PERL_GET_CONTEXT; \
            PERL_SET_CONTEXT(parent_perl); { \
                                PerlInterpreter *my_perl = parent_perl;
#define LEAVE_TLS_CONTEXT \
                                        } PERL_SET_CONTEXT(current_perl);
#else
#define GET_TLS_CONTEXT         /* TLS context not enabled */
#define ENTER_TLS_CONTEXT       /* TLS context not enabled …
Run Code Online (Sandbox Code Playgroud)

perl multithreading xs

5
推荐指数
1
解决办法
799
查看次数

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

无论perlcall(在"策略存储回调上下文信息"一节),并延伸和嵌入Perl(以下简称"回调"一节)列出了3点不同的方式来处理从XS/C调用的Perl子例程:

  1. 马上:XS打电话
  2. 延迟:将子ref保存为SV*以供日后使用
  3. 多个:保存n个子参考以供日后使用

上面针对#3列出的示例和细节使用XS中的散列来将子ref与特定C函数相关联,但是它们预定义了固定数量的C函数,这是不合适的.

我正在使用一个XS接口到一个C库,它使用带有可选参数的回调/函数指针,例如:

  blah(custom_type *o, void (*func) (void *data, int more_data), const void * data);
Run Code Online (Sandbox Code Playgroud)

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

如果可能的话,我想将C API的一对一映射到Perl.例如

  blah($o, \&func, $data);
Run Code Online (Sandbox Code Playgroud)

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

我将如何实施上述#3?

perl xs

5
推荐指数
1
解决办法
783
查看次数

如何有条件地将C代码片段编译到我的Perl模块?

我有一个模块,将针对几种不同的操作系统和配置.有时,一些C代码可以使这个模块的任务更容易一些,所以我有一些C函数,我想绑定代码.我不具备绑定C函数-我不能保证最终用户甚至有一个C编译器,例如,它通常不是优雅地故障转移到完成同样的事情的纯Perl的方式有问题 - 但如果我可以从Perl脚本调用C函数,那就太好了.

还在我这儿?这是另一个棘手的部分.几乎所有的C代码都是特定于系统的 - 为Windows编写的函数不能在Linux上编译,反之亦然,而在Solaris上执行类似操作的函数看起来会完全不同.

#include <some/Windows/headerfile.h>
int foo_for_Windows_c(int a,double b)
{
  do_windows_stuff();
  return 42;
}
Run Code Online (Sandbox Code Playgroud)
#include <path/to/linux/headerfile.h>
int foo_for_linux_c(int a,double b)
{
  do_linux_stuff(7);
  return 42;
}
Run Code Online (Sandbox Code Playgroud)

此外,即使对于同一系统的本机代码,也可能只能在任何特定配置上编译其中一些.

#include <some/headerfile/that/might/not/even/exist.h>
int bar_for_solaris_c(int a,double b)
{
  call_solaris_library_that_might_be_installed_here(11);
  return 19;
}
Run Code Online (Sandbox Code Playgroud)

但理想情况下,我们仍然可以使用可以使用该配置进行编译的C函数.所以我的问题是:

  • 如何有条件地编译C函数(只编译适合当前值的代码$^O)?

  • 如何单独编译C函数(某些函数可能无法编译,但我们仍然想使用那些函数)?

  • 我可以在构建时(最终用户安装模块时)或在运行时(Inline::C例如)进行此操作吗?哪种方式更好?

  • 我如何判断哪些函数已成功编译并可从Perl中使用?

所有的想法赞赏!


更新:感谢所有回复的人.所以这就是我做的:

我考虑了一个与语句Inline::C内部 运行时绑定的方案eval,但最终确定了子类化Module::Build 和自定义ACTION_build方法:

my $builderclass = Module::Build->subclass(
 class => 'My::Custom::Builder',
 code => <<'__CUSTOM_BUILD_CODE__,',
 sub ACTION_build {
   use File::Copy;
   my …
Run Code Online (Sandbox Code Playgroud)

perl swig xs

5
推荐指数
1
解决办法
577
查看次数

如何在C代码中构建Perl哈希?

我希望在Perl中嵌入一个C代码.在这个C代码中,我想将一个巨大的文件读入内存,进行一些更改并构建一个哈希(一个自定义的).我希望从我的Perl代码中访问此哈希.可能吗?我怎样才能达到目标?

c perl hash xs

5
推荐指数
2
解决办法
1504
查看次数

Perl XS和C++将指针传递给缓冲区

我知道几乎没有C++,所以没有帮助,而我的XS并没有好多少.我正在为C++库创建一个XS接口,我几乎所有的方法都在工作,除了一个.

Perl中的方法应如下所示:

$return_data = $obj->readPath( $path );
Run Code Online (Sandbox Code Playgroud)

该方法定义为.h文件:

int readPath(const char* path, char* &buffer, bool flag=true);
Run Code Online (Sandbox Code Playgroud)

如果以"NULL"传递,"缓冲区"将被分配.

另外两个版本的readPath具有不同的签名,但它们不是我想要的版本.(有趣的是,当我尝试编译时,它告诉我"候选人"是我不想要的两个.)那是因为它不理解"char*&"吗?

有人可以帮助我需要写的xsub吗?

我在使用Perl 5.14.2.

顺便说一句 - 我还使用了一个类型映射"long long int"到T_IV.我找不到任何关于如何正确键入long long长度的文档.任何建议我应该如何长期打字?

谢谢,

perl xs

5
推荐指数
1
解决办法
539
查看次数

sv_catpv()和sv_catpvs()之间有什么区别?

根据perlapi,sv_catpv()工作原理如下:

NUL-terminated字符串连接到SV中字符串的末尾.如果SV设置了UTF-8状态,则附加的字节应该是有效的UTF-8.处理'获得'魔法,但不是'设置'魔法.

void sv_catpv(SV *const sv, const char* ptr)

sv_catpvs()不过我发现的大多数XS教程都使用了这个:

喜欢sv_catpvn,但是采用文字字符串而不是字符串/长度对.

void sv_catpvs(SV* sv, const char* s)

嗯,这不是很有帮助,所以让我们来看看sv_catpvn():

将字符串连接到SV中字符串的末尾.该len指示要复制的字节数.如果SV设置了UTF-8状态,则附加的字节应该是有效的UTF-8.处理'获得'魔法,但不是'设置'魔法.

void sv_catpvn(SV *dsv, const char *sstr, STRLEN len)

所以,sv_catpvn做同样的事情,sv_catpv只不过它采用的字符串长度作为一个单独的参数,并且sv_catpvs是一样的sv_catpvn,只不过它采用的文本字符串.

有有一些细微的差别sv_catpvsv_catpvs我失踪,或者他们只是两种方法做同样的事情?

perl xs

5
推荐指数
1
解决办法
130
查看次数

如何在 Perl 哈希中存储 null

我想在我的 C 代码 (XS) 中使用 Perl 哈希作为一个集合,所以我只需要在哈希中保留键。是否可以存储 null 或其他常量值之类的内容以避免创建不必要的值?

像这样的东西:

int add_value(HV *hash, SV *value)
{
    // just an example of key
    char key[64];
    sprintf(key, "%p", value);
    if (hv_exists(hash, key, strlen(key)) return 0;

    // here I need something instead of ?
    return hv_stores(hash, key, ?) != NULL;
}
Run Code Online (Sandbox Code Playgroud)

可能的解决方案之一可能是存储值本身,但可能有特殊的常量 forundef或 null。

perl xs

5
推荐指数
2
解决办法
815
查看次数

Perl XS:内存管理

我是Perl XS的新手.

我的简单测试函数获取一个字符串并附加一些内容.在Perl中是一个标量字符串输入和输出.

在函数中我有一个malloc.什么是正确的释放mem的方法?

SV *foo (str)
   SV *str
CODE:
    unsigned char *strbuf;
    size_t strlen;
    strbuf = (unsigned char *) SvPV (str, strlen);

    int n = strlen + 10;
    unsigned char *buf = malloc (n);    

    strncpy (buf, strbuf, strlen);
    strncat (buf, "0123456789", 10);

    RETVAL = newSVpv (buf, n);
OUTPUT:
    RETVAL
Run Code Online (Sandbox Code Playgroud)

谢谢!克里斯

c perl xs

5
推荐指数
1
解决办法
167
查看次数

标志'pIOK`是什么意思?

Devel::Peek我倾倒perl SV时,我可以看到:

SV = IV(0x1c13168) at 0x1c13178
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 2
Run Code Online (Sandbox Code Playgroud)

但找不到描述是什么pIOK意思.

我想看看它在Devel::Peek,perlapi,perlguts,perlxs...在来源,我发现:

{SVp_IOK, "pIOK,"}
Run Code Online (Sandbox Code Playgroud)

但还是找不到什么SVp_IOK.它是什么?

UPD
我找到了这个文件.它揭示了旗帜的含义以及它们所处的位置.(要小心这个DOC已经过时了)

在此输入图像描述

此标志指示对象具有有效的非公共IVX字段值.它只能为值类型SvIV或其子类型设置.

UPD

为什么私人和公共旗帜不同

perl xs perlapi

5
推荐指数
1
解决办法
197
查看次数

标签 统计

perl ×10

xs ×10

c ×2

cpan ×1

hash ×1

module ×1

multithreading ×1

perl-module ×1

perlapi ×1

swig ×1