从Julia更新C结构的字段值 [英] Updating a field value of a C struct from Julia

查看:64
本文介绍了从Julia更新C结构的字段值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题很简单,但是我不知道做到这一点的最佳方法(或者Julia现在不提供这种方法):如何设置Julia的C结构的字段值?

My question is simple but I don't know the best way to do that (or Julia doesn't offer such a way at the moment): how can I set a field value of a C struct from Julia?

想象一下,您有一个结构类型来表示C库中树的节点:

Imagine you have a struct type to represent a node of a tree in a C library:

typedef struct node_s
{
    int type;
    node_t* next;
    node_t* children;
    node_t* parent;
} node_t;

并复制到Julia中:

and copy it in Julia:

immutable node_t
    typ::Cint
    next::Ptr{node_t}
    children::Ptr{node_t}
    parent::Ptr{node_t}
end

现在假定您有一个指向C中分配的node_t的指针,并且想要更新Julia中的parent字段.我知道我们有unsafe_store!来更新指针指向的值,但是计算parent字段的指针偏移量比较麻烦(在这种情况下,在我的64位计算机上为sizeof(Int) + sizeof(Ptr{node_t}) * 2).有没有更简单的方法可以做同样的事情?

Now assume that you have a pointer to node_t allocated in C and want to update the parent field in Julia. I know we have unsafe_store! to update a value pointed by a pointer, but it's cumbersome to calculate the pointer offset of the parent field (in this case, it would be sizeof(Int) + sizeof(Ptr{node_t}) * 2 on my 64-bit machine). Is there any simpler way to do the same thing?

推荐答案

为此用例提供了fieldoffset函数:

julia> immutable node_t
           typ::Cint
           next::Ptr{node_t}
           children::Ptr{node_t}
           parent::Ptr{node_t}
       end

julia> fieldoffset(node_t, 1)
0x0000000000000000

julia> fieldoffset(node_t, 2)
0x0000000000000008

julia> fieldoffset(node_t, 3)
0x0000000000000010

julia> fieldoffset(node_t, 4)
0x0000000000000018

但是也不必担心只存储整个immutable,而只更改了一个字段.它将被优化掉.

But also don't be worried about simply storing the whole immutable, with one field changed; it will be optimized away.

julia> k = Ptr{node_t}(Libc.malloc(sizeof(node_t)))
Ptr{node_t} @0x00000000036194c0

julia> unsafe_load(k)
node_t(29544064,Ptr{node_t} @0x3038662d34363a34,Ptr{node_t} @0x3a386e2d3832313a,Ptr{node_t} @0x34363a32333a3631)

julia> update_parent(x::node_t, n::Ptr{node_t}) =
           node_t(x.typ, x.next, x.children, n)
update_parent (generic function with 1 method)

julia> mutate!(k) = unsafe_store!(k, update_parent(unsafe_load(k), Ptr{node_t}(0)))
mutate! (generic function with 1 method)

julia> @code_llvm mutate!(k)

define %node_t* @"julia_mutate!_70963"(%node_t*) #0 {
top:
  %1 = load %node_t, %node_t* %0, align 1
  %.fca.3.insert = insertvalue %node_t %1, %node_t* null, 3
  store %node_t %.fca.3.insert, %node_t* %0, align 1
  ret %node_t* %0
}

这篇关于从Julia更新C结构的字段值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆