julia - Julia ccall 接口(interface)和符号的问题

标签 julia

我正在尝试使用 Julia 的 ccall与 C 库接口(interface)的函数。所有类型和指针都是正确的,并且下面的函数调用成功地返回了正确的答案(为简洁起见,此处未显示变量定义和设置)。

    ccall((:vDSP_convD, libacc),  Void,
          (Ptr{T}, Int64,  Ptr{T},  Int64,  Ptr{T},  Int64, UInt64, UInt64),
          x_padded, 1, pointer(K, Ksize), -1, result, 1,  Rsize, Ksize)

但是,如果我希望将函数名生成为符号,然后将其用作 ccall 的参数, 它失败。
fname = symbol(string("vDSP_conv", "D"))
ccall((fname , libacc),  Void,
          (Ptr{T}, Int64,  Ptr{T},  Int64,  Ptr{T},  Int64, UInt64, UInt64),
          x_padded, 1, pointer(K, Ksize), -1, result, 1,  Rsize, Ksize)

错误是:
ERROR: LoadError: TypeError: conv: in ccall: first argument not a 
pointer or valid constant expression, expected Ptr{T}, 
got Tuple{Symbol,ASCIIString}

如果我打印这两个命名版本中的每一个的类型,我会得到
julia> println(typeof(:vDSP_convD))
       Symbol
julia> println(typeof(fname))
       Symbol

有没有办法让它工作?我猜我将不得不将它包装在一个宏或 @eval 中。完成这项工作,但我很好奇为什么上述功能不能如图所示工作?

任何帮助将不胜感激!

编辑

我最终将它包装在 @eval 中阻止让它工作;但是,我仍然对后端逻辑感到好奇,为什么上面的语法不起作用(为什么它有时将符号解释为指针,而不是其他时候)

最佳答案

ccall并不是真正的函数——它是一种使用 C ABI 转换为 C 函数调用的句法形式。要发出对 C 函数的调用,您需要能够静态解析函数的地址——这就是这个要求的来源。请注意,在 C 和 Julia 中,您还可以使用变量函数指针调用函数。在 Julia 中,有几种方法可以获得这样的指针,通常使用 dlopendlsym .什么ccall不会做的是通过非常量名称解析函数:这在 C 中是不可能的(无需自己构建查找表);在 Julia 中,您可以通过使用 eval 来做到这一点,正如您所知道的那样– 但是这样做会产生编译器开销。这就是为什么ccall不会自动执行此操作:例如,您不想冒在循环中意外引入编译器开销的风险。

关于julia - Julia ccall 接口(interface)和符号的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35831775/

相关文章:

plot - 如何使用 Plots.jl 缩放字体大小

dataframe - 相关矩阵的Julia DataFrame,如何提取高相关的单元格值和列?

julia - Julia 中的单项式向量

julia-lang 中的直方图计算

plot - IJulia 情节 One Liner

visual-studio-code - 如何在 VS 代码中设置 Julia?

arrays - Julia 中以 DataArrays 和 Arrays 作为参数的函数

matplotlib - julia notebook 交互窗口 pyplot

tuples - 如何在 julia 中将 Tuple{Array{Float64,1},Array{Float64,1}} 转换为 Array{Tuple{Float64,Float64},1}

optimization - 一个快速编码技巧以某种方式最终使 Julia 中的代码变慢