Julia ccall接口和符号的问题

Rem*_*elt 6 julia

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

    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)
Run Code Online (Sandbox Code Playgroud)

但是,如果我希望将函数名称生成为符号,然后将其用作参数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)
Run Code Online (Sandbox Code Playgroud)

错误是:

ERROR: LoadError: TypeError: conv: in ccall: first argument not a 
pointer or valid constant expression, expected Ptr{T}, 
got Tuple{Symbol,ASCIIString}
Run Code Online (Sandbox Code Playgroud)

如果我打印这两个命名版本中的每一个的类型,我得到

julia> println(typeof(:vDSP_convD))
       Symbol
julia> println(typeof(fname))
       Symbol
Run Code Online (Sandbox Code Playgroud)

有没有办法让这个工作?我猜我必须将它包装在一个宏中或者@eval让它工作,但我很好奇为什么上面的功能不能如图所示?

任何帮助将非常感谢!

编辑

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

Ste*_*ski 9

ccall它实际上不是一个函数 - 它是一种使用C ABI转换为C函数调用的语法形式.要发出对C函数的调用,您需要能够静态地解析函数的地址 - 这就是此要求的来源.请注意,在C和Julia中,您还可以使用变量函数指针调用函数.在Julia中,有几种方法可以获得这样的指针,通常使用dlopendlsym.什么ccall不会做的是通过非恒名解析功能:这是不可能在C(没有建立自己查找表); 在朱莉娅,你可以这样做,正如你已经想到的那样,通过使用eval- 但这样做有编译器开销.这就是为什么ccall不自动执行此操作:例如,您不希望冒着在循环中意外引入编译器开销的风险.