c – 使用来自C的内存地址的Julia读/写结构数据
发布时间:2020-12-16 07:21:26 所属栏目:百科 来源:网络整理
导读:我将我的应用程序嵌入到Julia中,我需要一种从Julia和C读取/写入相同结构的好方法. 在Python中我可以简单地做到: ffi.cdef(""" struct keyboard_s { int forward; int backward; int left; int right; int jump; } struct keyboard_s *app_get_keyboard();""
我将我的应用程序嵌入到Julia中,我需要一种从Julia和C读取/写入相同结构的好方法.
在Python中我可以简单地做到: ffi.cdef(""" struct keyboard_s { int forward; int backward; int left; int right; int jump; } struct keyboard_s *app_get_keyboard(); """ app = ffi.dlopen("app.dll") thekeyboard = app.app_get_keyboard(); thekeyboard.forward = 1; # this would immediatly change the memory in C 但是,我在Julia和Julia中尝试这样的事情总是只是复制数据并且无法从C更改外部存储器地址: type keyboard_s forward::Int32 backward::Int32 left::Int32 right::Int32 jump::Int32 end # lets imply this would return the memory struct just like app_get_keyboard() # I just use malloc(sizeof(keyboard_s)) so everybody here can test for themselves... address = ccall(:malloc,(Int64),(Int64,),sizeof(keyboard_s)) # address is now a valid Int64 address,so lets map it as pointer of type keyboard_s ptr = Ptr{keyboard_s}(address) # thekeyboard contains now the random data from the c static memory thekeyboard = unsafe_load(ptr) # this will change only the value of "thekeyboard",# it doesn't touch C the Int64 address memory pointer... thekeyboard.forward = 123 # this has no effect on the real memory address :( # lets load the keyboard again from same address thekeyboard = unsafe_load(ptr) thekeyboard.forward == 123 # this is false! no effect whatsoever in C memory from Julia 我怎么能在Julia中与C共享结构的内存地址? 解决方法
好吧,我想出了一个很好的出路,这并不觉得太尴尬.我基本上重载[]运算符来通过符号访问struct字段,如下所示:
thekeyboard[:forward] = 123 代码: function offsetof(type_,member::Symbol) for (i,item) in enumerate(fieldnames(type_)) if item == member return fieldoffset(type_,i) end #print(typeof(i)) end # what to do when symbol not in type_? throw("$type_ has no member named $member") end function GetStructType(type_,item) in enumerate(fieldnames(type_)) if item == member return fieldtype(type_,i) end #print(typeof(i)) end # what to do when symbol not in type_? throw("$type_ has no member named $member") end function Base.getindex(ptr::Ptr{T},s::Symbol) where {T} address = UInt(ptr) if address == 0 throw("Base.getindex(Ptr::{$T}) would dereference a NULL pointer") end offset = offsetof(T,s) fieldtype = GetStructType(T,s) fieldptr = Ptr{fieldtype}(address + offset) #log("Symbol $s $ptrtype address=$address offset=$offset fieldtype=$fieldtype ptr=$ptr fieldptr=$fieldptrn") #return 123 return unsafe_load(fieldptr) end function Base.setindex!(ptr::Ptr{T},value,s::Symbol) where {T} address = UInt(ptr) if address == 0 throw("Base.setindex!(Ptr) would write to a NULL pointer") end offset = offsetof(T,s) fieldptr = Ptr{fieldtype}(address + offset) #log("Symbol $s $ptrtype address=$address offset=$offset fieldtype=$fieldtype ptr=$ptr fieldptr=$fieldptrn") unsafe_store!(fieldptr,value) return value end (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |