Problem with Julia ccall interface and characters

I use the Julia ccall function to interact with the C library. All types and pointers are correct, and the function call below returns the correct answer (a brief definition and setting are 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) 

However, if I want to generate the function name as a character, 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:

 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 versions of names, I get

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

Is there any way to make this work? I suppose I have to wrap this with a macro or @eval to get this working, but I am curious why the above functionality does not work as shown?

Any help would be appreciated!

EDIT

I ended up @eval it in the @eval block to make it work; However, I'm still curious about the backend logic about why the above syntax doesn't work (why does it sometimes interpret the character as a pointer, and then not others)

+5
source share
1 answer

ccall is not really a function - it is a syntactic form that translates into a call to a C function using C ABI. To emit a C function call, you must be able to statically resolve the address of the function — this is where this requirement comes from. Note that in both C and Julia, you can also call a function using a variable pointer. There are several ways in Julia to get such a pointer, usually using dlopen and dlsym . What ccall will not do is resolve the function with a mutable name: this is not possible in C (without building your own lookup table); in Julia you can do this as you understand using eval - but there is compiler overhead for that. Therefore, ccall will not do this automatically: you do not want to run the risk of accidentally entering compiler overhead in a loop, for example.

+7
source

Source: https://habr.com/ru/post/1244538/


All Articles