当我明确指定类型时,有人可以解释为什么这个ccall有效,但是Julia失败并且#34;错误解释ccall参数元组"当我使用typeof指定类型?
type Foo
end
type Boo
eq::Ptr{Foo}
buf::Array{Float32,1}
s::Array{UInt8,1}
end
function new_boo(p1, p2, p3, p4, p5)
b = Boo(C_NULL,zeros(p1*2),zeros(div(p1,2)))
eqref = Ref{typeof(b.eq)}(C_NULL)
res = ccall((:myfunc, "mydll.dll"), stdcall, Cint, (Ptr{typeof(b.eq)}, Int32, Int8, Int8, Int8, Int8),
eqref, p1, p2, p3, p4, p5)
b.eq = eqref[]
b
end
如果我打印Ptr{typeof(b.eq)}
和Ptr{Ptr{Foo}}
,它们会显示相同的内容。如果我与is()
进行比较,它们是平等的。有什么区别?我还尝试先将v = typeof(b.eq)
分配给变量,然后传递Ptr{v}
,但它没有帮助。
答案 0 :(得分:4)
typeof
是一个运行时函数,但在编译函数时,ccall
参数类型必须是静态可确定的。 (否则,Julia需要在每个ccall
周围插入一个警卫来捕捉不匹配的类型,使ccall
慢得多。
您最好的选择是在ccall
中指定固定类型,如您所发现的那样。
可以在函数声明中使用parametric type作为一个或多个参数,这将允许Julia为每个变体编译不同版本的函数(包括专用的ccall
)参数类型:
function new_boo{T}(p1::T, p2, p3, p4, p5)
...
res = ccall((:myfunc, "mydll.dll"), stdcall, Cint, (Ptr{T}, Int32, Int8, Int8, Int8, Int8), eqref, p1, p2, p3, p4, p5)
end
但是,这不太可能是正确的解决方案,除非您要么改变C函数名称,要么将指针传递给具有类型标记的某个结构。
请注意,如果您使用void*
样式的不透明指针反映C结构,则只需编写eq::Ptr{Void}
。