- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有一个元组 Cchar
像
str = ('f', 'o', 'o', '\0', '\0')
str
是
Vector
,我可以创建
Ptr
并用它做各种各样的事情。我尝试了各种传递方式
str
到
pointer
的方法,
Ptr
,
Ref
, 和
unsafe_string
没有成功,因为那些通常在数组而不是元组上工作。有什么建议么?
typedef struct foo {
char str[FOO_STR_MAX_SZ];
...
} foo_t;
struct foo_t
str :: NTuple{FOO_STR_MAX_SZ, UInt8}
...
end
NTuple
的
Cchar
(即
Int8
)而不是
UInt8
,我尝试使用
SVector
而不是
NTuple
也是。但我仍然找不到生成
Ptr
的方法来自
str
field 。我错过了什么吗?
最佳答案
既然你问了这个问题,我想把它收集到一个数组 a = collect(x.str)
不是你期待的答案...
您可以使用 ccall(:jl_value_ptr, Ptr{Cvoid}, (Any,), a)
获取a
的指针即使a
是不可变的。但是,一味地使用它会产生一些令人困惑的结果:
julia> struct foo_t
str::NTuple{2, UInt8}
end
julia> a = foo_t((2, 3))
foo_t((0x02, 0x03))
julia> ccall(:jl_value_ptr, Ptr{Cvoid}, (Any,), a.str)
Ptr{Nothing} @0x00007f4302c4f670
julia> ccall(:jl_value_ptr, Ptr{Cvoid}, (Any,), a.str)
Ptr{Nothing} @0x00007f4302cc47e0
NTuple
是不可变的,编译器会为它做很多“优化”,例如,每次使用时都要应对。这就是为什么在
source code 中明确禁止从不可变对象(immutable对象)获取指针的原因。 :
function pointer_from_objref(@nospecialize(x))
@_inline_meta
typeof(x).mutable || error("pointer_from_objref cannot be used on immutable objects")
ccall(:jl_value_ptr, Ptr{Cvoid}, (Any,), x)
end
a.str
复制元组,你可以避开这个表达式,直接使用
a
的地址计算它的地址和
fieldoffset(typeof(a), 1)
. (1 表示
str
是
foo_t
的第一个字段)
julia> p = Ptr{UInt8}(ccall(:jl_value_ptr, Ptr{UInt8}, (Any,), a)) + fieldoffset(typeof(a), 1)
Ptr{UInt8} @0x00007f4304901df0
julia> p2 = Ptr{UInt8}(ccall(:jl_value_ptr, Ptr{UInt8}, (Any,), a)) + fieldoffset(typeof(a), 1)
Ptr{UInt8} @0x00007f4304901df0
julia> p === p2
true
julia> unsafe_store!(p, 5)
Ptr{UInt8} @0x00007f4304901df0
julia> a
foo_t((0x05, 0x03))
julia> mut!(a) = unsafe_store!(Ptr{UInt8}(ccall(:jl_value_ptr, Ptr{UInt8}, (Any,), a)) + fieldoffset(typeof(a), 1), 8)
mut! (generic function with 1 method)
julia> mut!(a)
Ptr{UInt8} @0x00007f42ec560294
julia> a
foo_t((0x05, 0x03))
a
没有改变,因为,
foo_t
本身也是不可变的,将被复制到
mut!
,因此在函数内部所做的更改将不会在外部可见。为了解决这个问题,我们需要包装
a
在一个可变对象中给它一个稳定的堆地址。
Base.RefValue
可用于此目的:
julia> b = Base.RefValue(a)
Base.RefValue{foo_t}(foo_t((0x05, 0x03)))
julia> mut!(b) = unsafe_store!(Ptr{UInt8}(ccall(:jl_value_ptr, Ptr{UInt8}, (Any,), b)) + fieldoffset(typeof(b), 1) + fieldoffset(typeof(a), 1), 8)
mut! (generic function with 1 method)
julia> mut!(b)
Ptr{UInt8} @0x00007f43057b3820
julia> b
Base.RefValue{foo_t}(foo_t((0x08, 0x03)))
julia> b[]
foo_t((0x08, 0x03))
关于julia - 如何将 `Ptr` 获取到 `NTuple` 的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54889057/
我想创建类来处理 TTree: from ROOT import * from Exceptions import * import os.path class NTupleHandler:
我目前正在研究支持二进制操作的解析器。表示二元运算的想法是使用这种结构 struct Binary{T x = :(1+2*(3+4)) :(1 + 2 * (3 + 4)) julia> dump
假设我有一个元组 Cchar像 str = ('f', 'o', 'o', '\0', '\0') 我想将其转换为更传统的字符串。如果 str是 Vector ,我可以创建 Ptr并用它做各种各样的事
我正在使用 scikit learn 建立一个机器学习项目。输入数据是扁平的 ROOT NTuples。 过去我一直使用 root_numpy 将 NTuples 转换为保存在 h5 文件中的 pan
我想定义以 NTuples 作为参数但有大小限制的函数。 这个想法是声明类似的内容: foo(x::NTuple{K-1,Int},y::NTuple{K,Int}) where {K} = "ok"
我是一名优秀的程序员,十分优秀!