当我尝试从C中unsafe_load指针时,Julia得到错误的值

Lan*_*Guo 2 c julia

C代码:

typedef struct __kstring_t {
    size_t l, m;
    char *s;
} kstring_t;

kstring_t * get_ptr_of_kstr(int num){
    char * ch = (char *)malloc(num);
    kstring_t kstr = {0, num, ch};
    kstring_t *p = &kstr;
    printf("In C, kstr.l: %zu\n", p->l);
    printf("In C, kstr.m: %zu\n", p->m);
    printf("In C, kstr.s: %p\n", p->s);
    printf("In C, pointer to kstr: %p\n", p);
    return p;
};
Run Code Online (Sandbox Code Playgroud)

朱莉娅代码

type KStr
l::Csize_t
m::Csize_t
s::Ptr{Cchar}
end
Run Code Online (Sandbox Code Playgroud)

问题

当我ccall用来调用get_ptr_of_kstr并获取kstring_tin 的指针时Julia,使用unsafe_load来获取其值,但值似乎是错误的.消息如下:

In C, kstr.l: 0
In C, kstr.m: 100000
In C, kstr.s: 0x37b59b0
In C, pointer to kstr: 0x7fffe7d80b90
kstr = Ptr{HT.KStr} @0x00007fffe7d80b90
unsafe_load(kstr).s = Ptr{Int8} @0x00007fffe7d80b90
Run Code Online (Sandbox Code Playgroud)

值与... unsafe_load(kstr).s相同kstr.为什么?怎么解决?

Lut*_*mak 6

据我所知C,你堆栈分配kstr,p它是堆栈中的地址.之后get_ptr_of_kstr的回报,不要期待值保持不变.我认为你应该在堆中分配你的结构.


Mat*_*ieu 6

关于C部分(我不知道Julia和C之间的绑定):

kstring_t kstr = {0, num, ch};
Run Code Online (Sandbox Code Playgroud)

这将在上下文中分配kstr堆栈get_ptr_of_kstr().并且在函数退出后立即返回指向它的指针.之后您不能再使用,不能在C或您可能传递给它的任何其他程序中使用.

正如@LutfullahTomak暗示的那样,你应该:

  • 从分配它通过malloc()/calloc(),
  • 传递预先分配的指向函数的指针并填充其成员,
  • 将它声明为static函数体,这使得它成为一个全局变量,其范围仅减少为函数.请注意,这不是一个好习惯.

另请注意,您的C编译器会将每个struct成员与一个地址对齐,具体取决于其选项和#pragma pack(如果使用),因此每个字段的偏移量可能不是您或Julia所期望的.