gcc - 为 Julia 中的 C lib 使用构建 C 包装器

标签 gcc shared-libraries julia

我正在尝试在 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/

相关文章:

c++ - 在回溯期间检索 sigcontext

c++ - 用于初始化 std::vector<std::function<bool(std::string)>> 的初始化列表在 g++ 4.9.0 中给出错误,但在 Visual Studio 2013 中编译良好

c - Mac OS Sierra : checking whether the C compiler works. .. 没有

android - Android 上共享库的偏移量

regex - 如何生成与 Julia 中的正则表达式匹配的随机字符串?

statistics - Julia 中的基尼系数 : Efficient and Accurate Code

linux - 将缓冲区或 C 字符串复制到 std::string 的最快方法

c++ - 创建(和链接)库时的符号解析

cmake - find_library 或 link_directories 或 find_package?什么是更好的方法?错误 - 使用 cmake 链接库

metaprogramming - 消除Julia元编程中的各种引用机制