2016-03-06 14 views
5

Sto cercando di utilizzare la funzione ccall di Julia per interfacciare con una libreria C. Tutti i tipi e i puntatori sono corretti e la chiamata alla funzione seguente restituisce correttamente la risposta corretta (definizione delle variabili e impostazione non mostrata qui per brevità).Problema con Julia ccall interface and symbols

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) 

Tuttavia, se voglio generare il nome della funzione come un simbolo, e quindi utilizzarlo come argomento per ccall, non riesce.

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) 

L'errore è:

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

se stampo il tipo di ciascuna di queste due versioni di denominazione, ottengo

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

C'è un modo per ottenere questo lavoro? Sto indovinando che dovrò avvolgere questo in una macro o @eval per ottenere questo lavoro, ma sono curioso di sapere perché la funzionalità di cui sopra non funziona come mostrato?

Qualsiasi aiuto sarà più apprezzato!

EDIT

ho finito per avvolgere questo in un @eval blocco per farlo funzionare; tuttavia, sono ancora curioso della logica di backend sul motivo per cui la sintassi precedente non funziona (perché interpreta un simbolo come puntatore a volte, e quindi non altre volte)

+0

come dice il doc ["(: funzione," libreria ") la coppia deve essere costante"] (http://docs.julialang.org/en/latest/manual/calling-c-and-fortran-code/ # calling-c-and-fortran-code) – Gnimuc

+1

C'è un modo per farlo funzionare usando 'const' o' Pair() '? –

risposta

7

ccall non è realmente una funzione - è una forma sintattica che viene tradotta in una chiamata di funzione C utilizzando la C ABI. Per emettere una chiamata a una funzione C, è necessario essere in grado di risolvere staticamente l'indirizzo della funzione - è da lì che proviene questo requisito. Nota che sia in C che in Julia puoi anche chiamare una funzione usando un puntatore a funzione variabile. In Julia, ci sono alcuni modi per ottenere tale puntatore, in genere utilizzando dlopen e dlsym. Ciò che ccall non farà è risolvere una funzione con un nome non costante: ciò è impossibile in C (senza creare una tabella di ricerca); in Julia puoi farlo, come hai capito, usando eval - ma c'è un sovraccarico del compilatore per farlo. Questo è il motivo per cui lo ccall non lo farà automaticamente: non si vuole correre il rischio di introdurre accidentalmente l'overhead del compilatore in un ciclo, ad esempio.

+1

Grazie per la spiegazione illustrativa di 'ccall'; spiega tutto ciò che volevo sapere! –