朱莉娅在ccall中的类型

时间:2017-01-18 03:37:36

标签: types julia

当我明确指定类型时,有人可以解释为什么这个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},但它没有帮助。

1 个答案:

答案 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}