我理解这个问题涉及到特定于实现的域,但在这一点上,Rakudo/MoarVM的具体答案对我也有帮助.
我正在研究一些NativeCall模块,并想知道如何调试内存泄漏.一些内存在C库中处理,我在那里有一个很好的处理.我知道域名是我的责任,MoarVM在那里没有什么可以做的.我可以在MoarVM域中做什么?检查悬空物体,循环参考物等的最佳方法是什么?
在一系列操作结束时是否有一种方法,我认为我的所有Perl对象都超出范围说"运行垃圾收集并告诉我任何事情"?
我可以运行一些Rakudo/NQP/MoarVM特定代码来帮助我吗?这不是为了在生产中发布,只是为了在我开发时进行测试/诊断.
MoarVM中的垃圾收集提供了一个诱人的概述,但没有足够的信息让我对它做任何事情.
我有一个简单的测试文件,如下所示:
use v6.c;
use NativeCall;
sub fcntl(int32, int32 --> int32) is native { * }
sub close(int32 --> int32) is native { * }
my $fd := fcntl($*OUT.native-descriptor, 0);
say $fd;
close($fd);
返回的文件描述符是-1,这不是我想要的.但是当我在REPL中运行相同的代码时,我得到了我正在寻找的东西:
> use NativeCall
Nil
> sub fcntl(int32, int32 --> int32) is native { * }
sub fcntl (int32 $, int32 $ --> int32) { #`(Sub+{Callable[int32]}+{NativeCall::Native[Sub+{Callable[int32]},Str]}|17126514527616) ... }
> sub close(int32 --> int32) is native { * }
sub close (int32 $ --> int32) { #`(Sub+{Callable[int32]}+{NativeCall::Native[Sub+{Callable[int32]},Str]}|17126514527904) ... } …我正在尝试在Perl 6中声明以下C结构:
struct myStruct
{
    int A[2]; //<---NEED to declare this
    int B;
    int C;
};
我的问题是我不知道如何int A[2];使用内置的NativeCall api 声明该部件.
所以我所拥有的是:
class myStruct is repr('CStruct') {
    has CArray[int32] $.A;
    has int32 $.B;
    has int32 $.C;
};
但是,我知道该has CArray[int32] $.A;部分是错误的,因为它没有在我的结构中声明只占用2个int32大小的部分.
我试图得到这个NativeCall运行的例子:
use NativeCall;
class p_timespec is repr('CPointer') {
    has uint32 $.tv_sec;
    has long $.tv_nanosecs;
}
sub clock_gettime(uint32 $clock-id, p_timespec $tspec --> uint32) is native(Str) { * };
my p_timespec $this-time;
my $result = clock_gettime( 0, $this-time);
say "$result, $this-time";
它只是段错误,这是你使用指针时发生的事情,你不应该.在这种情况下,这可能是由于声明p_timespec; 我实际上已将其声明为a CPointer,尽管结构应该没问题.但是,从分段错误来看,我无法理解究竟是什么问题.有人可以帮忙吗?
我正在尝试为Cgraph创建Perl6绑定,并且其中一个结构为其某些属性设置了位字段,其值小于8。如何在模块中表示该字段?
我尝试使用is nativesize(x)特征定义自定义类型,但是CStructs仅支持8位宽倍数的类型。
C示例代码:
struct Agtag_s {
    unsigned objtype:2;
}
我试过的
my native objtype is repr('P6int') is Int is nativesize(2) is export { }
class Agtag is repr('CStruct') is export {
    has objtype $.object-type;
}
尝试将我的模块与该代码一起使用会失败,并显示以下错误消息:
CStruct only supports native types that are a multiple of 8 bits wide (was passed: 2)
我正在编写 Raku 绑定到 C 库,但不是要求 Raku 代码的用户自己安装 C 库,我想将 C 代码捆绑为发行版的一部分(它不是那么广泛分布式库)。
我读过有关发行版的%?RESOURCES,这似乎很有用。但是我对如何将其应用于此的具体细节感到模糊。
我是否可以将 C 源代码捆绑在发行版中,并指定某种方式使其作为安装的一部分进行编译(例如,使用zef)?或者我是否需要捆绑库的预编译版本,并获取代码以根据平台选择正确的版本?
或者这根本不可能,我应该向用户提供有关如何单独安装库的说明?
我有这个定义:
use NativeCall;
unit module kazmath;
class mat4 is repr('CStruct') {
    HAS num32 @.mat[16] is CArray;
}
sub kmMat4Fill( mat4 $mat, num32 @filler ) returns mat4 is native('kazmath')
                                            is export {*}
要绑定的函数在此处定义:
kmMat4* kmMat4Fill(kmMat4* pOut, const kmScalar* pMat);
返回的错误是:
Too many positionals passed; expected 2 arguments but got 3
我实在想不通。
我正在编写一个 C 库的接口。AC 函数分配一些内存,读取一个值,并返回一个void *指向该缓冲区的指针,随后将被释放。
我希望确保当我将调用的输出分配给nativecast(Str, $data)Raku Str 变量时,数据被分配给变量(复制到),而不仅仅是绑定到它,所以我可以释放 C 函数分配的空间任务完成后不久。
这大概是代码的样子:
my Pointer $data = c_read($source);
my Str $value = nativecast(Str, $data);
c_free($data);
# $value is now ready to be used
我通过 valgrind 运行此代码,它没有报告任何尝试引用已释放的内存缓冲区的情况。我还是很好奇。
我正在尝试从用 C 编写的共享库返回结构。这是简单的代码,用于测试返回结构和简单的 int32,libstruct.c编译者gcc -shared -Wl,-soname,libstruct.so.1 -o libstruct.so.1 libstruct.c:
#include <stdint.h>
int32_t newint(int32_t arg) {
    return arg;
}
struct MyStruct {
    int32_t member;
};
struct MyStruct newstruct(int32_t arg) {
    struct MyStruct myStruct;
    myStruct.member = arg;
    return(myStruct);
}
我可以通过简单的 C 程序来使用这个库,该程序usestruct.c由以下代码编译gcc -o usestruct usestruct.c ./libstruct.so.1:
#include <stdio.h>
#include <stdint.h>
struct MyStruct {
    int32_t member;
};
extern struct MyStruct newstruct(int32_t);
extern int32_t newint(int32_t);
int main() {
    printf("%d\n", newint(42));
    struct MyStruct myStruct;
    myStruct = newstruct(42); …我有一个 C 文件和一个 Raku 文件用于连接。有时我会得到随机且错误的值。文件如下
\nC 文件:它有一个名为 CField 的结构,Raku 代码将与该结构交互。重要的是它有一个动态分配的属性,即data. 所以我在 中进行了 2 个 malloc make_field,并在 中进行了 2 个 free free_field。
// field.c\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\nstruct CField {\n    void* data;\n    size_t size;\n};\n\nvoid* checker_malloc(size_t n) {\n    // malloc but checks if allocated fine\n    void* p = malloc(n);\n    if (!p) { fprintf(stderr, "can\'t allocate %zu bytes", n); exit(1); }\n    return p;\n}\n\nstruct CField* make_field(void* data, size_t data_size) {\n    // malloc for all struct\n    struct CField* new_field …