Julia Ccall界面和符号的问题 [英] Issue with Julia ccall interface and symbols

查看:160
本文介绍了Julia Ccall界面和符号的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm attemping to use Julia's ccall function to interface with a C library. All the types and pointers are correct, and the below function call successfully returns the correct answer (variable defintion and setup not shown here for brevity).

    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的参数,则它将失败.

However, if I wish to generate the function name as a symbol, and then use it as an argument to ccall, it fails.

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}

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

If I print the type of each of these two naming versions, I get

julia> println(typeof(:vDSP_convD))
       Symbol
julia> println(typeof(fname))
       Symbol

是否有办法使它正常工作?我猜想我必须将其包装在宏或@eval中才能完成这项工作,但是我很好奇为什么上述功能无法按所示方式工作?

Is there a way to get this to work? I'm guessing that I will have to wrap this in a macro or @eval to get this work, but I am curious as to why the above functionality doesn't work as shown?

任何帮助将不胜感激!

编辑

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

I ended up wrapping this in an @eval block to get it to work; however, I'm still curious as to the backend logic as to why the above syntax doesn't work (why it interprets a symbol as a pointer sometimes, and then not other times)

推荐答案

ccall并不是一个真正的函数-它是一种语法形式,可以使用C ABI转换为C函数调用.要发出对C函数的调用,您需要能够静态解析该函数​​的地址-这就是要求的来源.请注意,在C和Julia中,您都可以使用变量函数指针来调用函数.在Julia中,有几种获取此类指针的方法,通常是使用dlopendlsym. ccall不能通过非常量名称解析函数:在C语言中这是不可能的(没有自己建立查找表的功能);如您所知,在Julia中可以使用eval来执行此操作-但是这样做会增加编译器的开销.这就是ccall不会自动执行此操作的原因:例如,您不想冒意外在循环中引入编译器开销的风险.

ccall is not really a function – it's a syntactic form that is translated to a C function call using the C ABI. To emit a call to a C function, you need to be able to statically resolve the address of the function – that's where this requirement comes from. Note that in both C and Julia you can also call a function using a variable function pointer. In Julia, there are a few ways to get such a pointer, typically by using dlopen and dlsym. What ccall won't do is resolve a function by non-constant name: this is impossible in C (without a building yourself a lookup table); in Julia you can do this, as you've figured out, by using eval – but there is compiler overhead to doing this. That is why ccall won't do this automatically: you don't want to run the risk of accidentally introducing compiler overhead in a loop, for example.

这篇关于Julia Ccall界面和符号的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆