Raku NativeCall 到 SOD 分段错误

Kha*_*rai 10 raku

我正在尝试在 Raku 中使用sodNativeCall,但我不断收到分段错误错误。

#!/usr/bin/env raku
use v6.d;
use NativeCall;

class Image is repr('CStruct') {
    has int32 $.h;
    has int32 $.w;
    has int32 $.c;
    has Pointer[num32] $.data;
}

sub sod_make_random_image(
    int32 $h,
    int32 $w,
    int32 $c,
) returns Image is native("$*CWD/sod") { * }


sub sod_img_save_as_png(
    Image $img,
    Str $filename,
    --> uint8 ) is native("$*CWD/sod") { * }


my $img = sod_make_random_image(100, 100, 3);
say sod_img_save_as_png($img, "test.png");
Run Code Online (Sandbox Code Playgroud)

我编译了运行的库gcc -shared -Wall -fPIC -o libsod.so sod.c -std=c99rakudo-gdb-m然后bt full输出:

0x00007fffef6939e3 in sod_make_random_image () from /media/khalid/Data/CommaProjects/SOD/libsodreader.so
(gdb) bt full
#0  0x00007fffef6939e3 in sod_make_random_image () from /media/khalid/Data/CommaProjects/SOD/libsodreader.so
No symbol table info available.

#1  0x00007ffff79c25b2 in dcCall_x64_sysv () from //home/khalid/.rakubrew/versions/moar-2023.05/install/lib/libmoar.so
No symbol table info available.

#2  0x0000000000000016 in ?? ()
No symbol table info available.

#3  0x00007fffffffd2b0 in ?? ()
No symbol table info available.

#4  0x00007ffff79c23fa in dc_callvm_call_x64 () from //home/khalid/.rakubrew/versions/moar-2023.05/install/lib/libmoar.so
No symbol table info available.

Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Run Code Online (Sandbox Code Playgroud)

知道为什么我会收到分段错误错误吗?此外sod_img_load_from_file始终返回宽度和高度为零的空图像。

小智 9

实际的问题是库的接口。返回sod_make_random_image() 值而不是指针,而 raku 期望 是一个指针这会扰乱调用堆栈,从而导致段错误sod_imgImage

为了测试我改变了sod_make_random_image返回一个指针:

sod_img *sod_make_random_image(int w, int h, int c)
{
    printf("w: %i  h: %i  c: %i\n", w, h, c);
    sod_img out = sod_make_empty_image(w, h, c);
    out.data = calloc(h*w*c, sizeof(float));
    if (out.data) {
        int i;
        for (i = 0; i < w*h*c; ++i) {
            out.data[i] = (rand_normal() * .25) + .5;
        }
    }
    return &out;
}
Run Code Online (Sandbox Code Playgroud)

并进行了相应的调整sod.h,并且成功了。当然,除了问题转移到sod_img_save_as_png()现在正在获取指针而不是它期望的值,但这也可以解决。

在我看来,您有两个选择:要么创建库的分支,以便返回 sod_img (和其他 structs )并将其作为指向结构的指针传递,要么为您想要使用取消引用的函数创建自己的包装器传递给实际函数的指针参数并获取结构返回值的指针。