perl xs - 从 c 数组返回 perl 数组

2024-05-10

使用 XS,我尝试将值从 C 数组传递到可在脚本中使用的 Perl 数组。

这是我的 xs 文件中的代码:

AV *
DoubleArray::getPerlArray()
    CODE:
    r = newAV();
    for(size_t i=0; i < THIS->count; i++)
    {
        av_push(RETVAL,newSVnv(THIS->data[i]));
    }
    OUTPUT:
    RETVAL

它编译得很好,但是当我在 perl 中运行以下命令时:

my @d = $C->getPerlArray();
foreach(@d)
{
    print "$_\n";
}

它只是打印ARRAY(0x1408cdc)当我期望它打印一个数字列表时。

如何修改我的代码以正确传回 perl 数组?


Perl subs 只能返回(0 个或更多)标量。当您尝试返回一个数组时(不使 Perl 崩溃是不可能的!),默认类型映射返回对该数组的引用。

请注意,您的程序也会泄漏内存(因为默认类型映射AV*应该使你的数组​​死亡,但没有)。


返回引用,方法 1

AV* /* Returns: sv_2mortal(newRV(RETVAL)) */
DoubleArray::getPerlArrayRef()
    PREINIT:
        size_t i;
    CODE:
        RETVAL = (AV*)sv_2mortal((SV*)newAV());
        for (i=0; i < THIS->count; ++i) {
            av_push(RETVAL, newSVnv(THIS->data[i]));
        }

    OUTPUT:
       RETVAL

内存泄漏检查:

  • Array's refcnt: 1 (newAV) -1[delayed] (sv_2mortal) +1 (newRV) = 1[delayed] (owned by reference)
  • Reference's refcnt: 1 (newRV) -1[delayed] (sv_2mortal) = 0[delayed]

Perl:

my $array = $C->getPerlArrayRef();
say for @$array;

返回引用,方法 2

SV* /* Returns: sv_2mortal(RETVAL) */
DoubleArray::getPerlArrayRef()
    PREINIT:
        AV* av;
        size_t i;
    CODE:
        av = newAV();
        RETVAL = newRV_noinc((SV*)av);
        for (i=0; i < THIS->count; ++i) {
            av_push(av, newSVnv(THIS->data[i]));
        }

    OUTPUT:
       RETVAL

内存泄漏检查:

  • 数组的 refcnt: 1 (newAV) +0 (newRV_noinc) = 1(由引用拥有)
  • Reference's refcnt: 1 (newRV_noinc) -1[delayed] (sv_2mortal) = 0[delayed]

Perl:


返回引用,方法 3

void
DoubleArray::getPerlArrayRef()
    PREINIT:
        AV* av;
        size_t i;
    PPCODE:
        av = newAV();
        mXPUSHs(newRV_noinc((SV*)av));
        for (i=0; i < THIS->count; ++i) {
            av_push(av, newSVnv(THIS->data[i]));
        }

内存泄漏检查:

  • 数组的 refcnt: 1 (newAV) +0 (newRV_noinc) = 1(由引用拥有)
  • Reference's refcnt: 1 (newRV_noinc) -1[delayed] (mXPUSHs) = 0[delayed]

Perl:


返回标量

我们必须检查上下文,因为我们不能在列表上下文之外的堆栈上放置多个标量。

void
DoubleArray::getElements()
    PREINIT:
        size_t i;
        U8 gimme = GIMME_V;
    PPCODE:
        if (gimme == G_ARRAY) {
            EXTEND(SP, THIS->count);
            for (i=0; i < THIS->count; ++i) {
                mPUSHn(THIS->data[i]);
            }
        }
        else if (gimme == G_SCALAR) {
            mXPUSHu(THIS->count);
        }

Perl:

my $count = $C->getElements();
say $count;

my @array = $C->getElements();
say for @array;

注意:refcnt 递减sv_2mortal被延迟,直到调用者有机会增加 refcnt。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

perl xs - 从 c 数组返回 perl 数组 的相关文章

  • 为什么 char 数组需要 strcpy 而 char star 不需要 - 在 C 中使用结构

    我对这段代码有一个误解 typedef struct EXP int x char name char lastName 40 XMP main XMP a a name eaaa a lastName strcpy a lastName
  • 帕斯卡三角形定位

    我编写了一个打印出帕斯卡三角形的Java程序 但是我不知道如何正确定位它 方案1 public class Triangle public static void main System out println nTriangle int
  • 如何只读取文件的第一行

    我已经用谷歌搜索了一段时间 但我找不到只读取文件第一行的函数 我需要读取文本文件的第一行并从中提取日期 Perl 新手 open my file lt filename txt my firstLine lt file gt close f
  • 在数组/对象中查找项目的最快方法

    在 Javascript AS3 中查找列表或对象中项目的索引的最快方法是什么 我对这两种语言都提出这个要求 因为这两种语言的语法相似 假设 myArray one two three myObject one 1 two 2 three
  • 如何过滤掉数组的数组

    您好 我有一个包含多个值的数组 我想尝试过滤掉搜索栏的索引 英语术语的一个例子是这样的 给我名称 Name2 的索引 并通过检查每个索引的第一个值中的所有字符串来执行此操作 Code Multiple Errors var received
  • 执行数组内的函数

    是否可以从数组内部执行匿名函数 也在数组内部定义 return execute function logic 或者我应该在外面定义它然后再调用它 从技术上讲 您可以将该函数括在括号中并像这样调用它 return function retur
  • 如何在 Perl 中找到正则表达式匹配的位置?

    我需要编写一个接收字符串和正则表达式的函数 我需要检查是否有匹配并返回匹配的开始和结束位置 正则表达式已经由qr 该函数还可能收到一个 全局 标志 然后我需要返回所有匹配的 开始 结束 对 我无法更改正则表达式 甚至无法添加 用户可能使用的
  • 在 Perl 中解析 RSS/Atom 的最佳库是什么? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我注意到XML RSS 解析器 http search cpan org dist XML RSS P
  • 过滤数组以获取唯一字段值

    我知道有很多方法可以过滤数组中的唯一值 但是如何过滤数组中具有给定字段的唯一值的对象呢 例如我有 obj1 obj2 obj3 其中每个对象具有以下形式 firstName lastName 如何过滤数组以最终得到一个最终数组 其中所有对象
  • 使用 OpenCV 描述符与 findFundamentalMat 匹配

    我之前发布了有关同一程序的问题 但没有收到答案 我已经纠正了当时遇到的问题 但又面临新的问题 基本上 我使用未校准的方法自动校正立体图像对的旋转和平移 我使用 SURF 等特征检测算法来查找两个图像 左右立体图像对 中的点 然后再次使用 S
  • C# 3维数组

    我想将 3 维数组中的 ARRAY 存储到buildingCostIds 中 但它说我必须有第三个数字 public static int buildingCost 0 1 2 5 5 5 public static void addBui
  • 使用 ImapMailbox.php 按日期对 Imap 邮箱进行排序

    我有一个客户支持系统 它会在收到电子邮件时创建电子邮件 我曾经使用后缀和特殊配置来获取电子邮件以添加额外的功能 例如 我想包含从电子邮件发送的附件 系统不会执行此操作 而是创建一封带有主题的电子邮件 因此我可以通过匹配主题来包含附件 我使用
  • 如何使用 Perl 和正则表达式将 SQL 文档转换为 ColdFusion 脚本?

    我需要将 SQL 语句文档转换为 ColdFusion 文档 我对正则表达式只有一点经验 而且我是 Perl 超级新手 我昨天刚刚自学了它的基础知识 所以我可以完成这项任务 我正在尝试用 Perl 编写的脚本匹配和替换模式 该脚本保存为 B
  • 给定一个零索引数组 & 该数组的平衡索引[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给出一个由 N 个整数组成的零索引数组 A 该数组的平衡索引是任何整数 P 满足 0 P 例如 考虑以下由 N 8 个元素组成的数组
  • ActiveRecord 嵌套 SELECT——我可以在没有手动 SQL 的情况下完成它吗?

    我有一张桌子 上面有 除其他外 一个名字和一个等级 我想返回所有唯一名称的集合 但对于返回的每个名称 我想选择排名最高的行 这很简单 有两个嵌套的 SELECT 语句 SELECT FROM SELECT FROM foo ORDER BY
  • 如何将文件中的行读入数组?

    我正在尝试将文件作为行数组读入 然后使用 zsh 对其进行迭代 我得到的代码在大多数情况下都有效 除非输入文件包含某些字符 例如括号 这是它的一个片段 bin zsh LIST cat path to some file txt SIZE
  • 如何连接以逗号分隔的命名范围的返回值

    我花了几个小时试图找出如何连接命名范围中的返回值 但结果是 运行时错误 32 类型不匹配 作为一个新手 我仍在与数组作斗争 所以也许我忽略了一些细节 谢谢你帮助我 示例 B1 苯 B2 柴油 B3 混合动力 gt E1 汽油 E2 柴油 E
  • 使用排序函数按 NSDates 对数组进行排序[重复]

    这个问题在这里已经有答案了 我有一个名为的模型类Event import Foundation import MapKit public class Event let id Int var title String let status
  • 我可以在 VIM 或 Perl 中替换单个正则表达式中的多个项目吗?

    假设我有字符串 The Quick Brown Fox Jumps Over the Lazy Dog 我可以用一个正则表达式将其更改为 The Slow Brown Fox Jumps Over the Energy Dog 吗 目前 我
  • 如何使用 Perl 在 Unix 中获取文件创建时间

    如何使用 perl 在 unix 中获取文件创建时间 我有这个命令显示文件的最后修改时间 perl MPOSIX le print strftime d b Y H M localtime lstat 9 for ARGV file txt

随机推荐