我正在尝试在 Julia 中使用 FANN(一个 C 库)。我需要编写一个 C 包装器来将内容转换为 void * 等。
我的问题是,当我尝试从 Julia 调用我的 C 包装器时,它无法找到 libfann.so 函数: “ Julia :符号循环错误:--- undefined symbol :fann_create_standard”。
我怀疑问题是因为 libfann 只是从我的 C 包装器链接到的,并未完全包含在内。
这是我构建它的方法:
myfann.c
#include "fann.h"
void * create_standard( unsigned int nl, unsigned int ni, unsigned int nnh, unsigned int no )
{
fann *ann = fann_create_standard(nl,ni,nnh,no);
void* retval = fann;
return retval;
}
... // other methods
juliafann.jl
ptr = ccall( (:create_standard, "libjlfann"), Ptr{Void}, (Uint32,Uint32,Uint32,Uint32), 3, 2, 3, 1)
ccall( (:destroy, "libjlfann"), Void, (Ptr{Void},), ptr)
用于编译的bash脚本:
gcc -Wall -fPIC -c myfann.c -lfann -lm
gcc -shared -o libjlfann.so -Wl,--whole-archive /usr/local/lib/libfann.so -Wl,--no-whole-archive -Wl,-soname,libjlfann.so.1 -o libjlfann.so.1.0 *.o
sudo rm /opt/lib/libjlfann*
sudo mv libjlfann.so.1.0 /opt/lib
sudo ln -sf /opt/lib/libjlfann.so.1.0 /opt/lib/libjlfann.so.1
sudo ln -sf /opt/lib/libjlfann.so.1.0 /opt/lib/libjlfann.so
然后我用“julia juliafann.jl”运行我的 julia 程序,然后出现错误。 Julia 可以很好地找到导出的函数,只是当它尝试评估我试图包装的原始 fann 库中的函数时会失败。
谢谢。这个问题应该足够普遍,可以适用于在 Julia 中使用的任意 C 包装器。
最佳答案
这里有一个解决总体问题的方法:使用 Julia 的 FANN。这不是子问题的解决方案:将共享库嵌入另一个共享库。
使用包装 C 库并不是绝对必要的。可以直接从 Julia 进行调用。
假设您的计算机上安装了 fann,与 C 版本 here 相比,以下内容会从 Julia 产生相同的输出.
test_neural.jl
num_input = 2
num_output = 1
num_layers = 3
num_neurons_hidden = 3
desired_error = 0.001
max_epochs = 500000
epochs_between_reports = 1000
type NeuralNet
ptr::Ptr{Void}
function NeuralNet( nLayers::Integer, nInputs::Integer, nHidden::Integer, nOutput::Integer)
ptr = ccall( (:fann_create_standard, "libfann"), Ptr{Void}, (Uint32,Uint32,Uint32,Uint32), nLayers, nInputs, nHidden, nOutput)
smart_p = new(ptr)
finalizer(smart_p, obj -> ccall( (:fann_destroy, "libfann"), Void, (Ptr{Void},), obj.ptr) )
smart_p
end
end
ann = NeuralNet( num_layers, num_input, num_neurons_hidden, num_output )
FANN_SIGMOID_SYMMETRIC = 5; // determined by looking at source
ccall( (:fann_set_activation_function_hidden, "libfann"), Void, (Ptr{Void},Uint32), ann.ptr, FANN_SIGMOID_SYMMETRIC)
ccall( (:fann_set_activation_function_output, "libfann"), Void, (Ptr{Void},Uint32), ann.ptr, FANN_SIGMOID_SYMMETRIC)
ccall( (:fann_train_on_file, "libfann"), Void, (Ptr{Void},Ptr{Uint8},Uint32,Uint32,Float32), ann.ptr, bytestring("xor.data"), max_epochs, epochs_between_reports, desired_error )
ccall( (:fann_save, "libfann"), Void, (Ptr{Void},Ptr{Uint8}), ann.ptr, bytestring("xor_float.net"))
# execution
input = [-1 -1]
calc_out = ccall( (:fann_run, "libfann"), Ptr{Float32}, (Ptr{Void},Ptr{Float32}), ann.ptr, float32(input) )
@printf("xor test (%f,%f) -> %f\n", input[1], input[2], unsafe_load(calc_out, 1))
关于gcc - 为 Julia 中的 C lib 使用构建 C 包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23702841/