从C调用本地Julia程序包

时间:2019-05-03 12:43:07

标签: c julia

Julia文档显示了如何从C调用Base Julia函数的示例(例如sqrt),我已成功复制了该示例。我真正感兴趣的是调用本地开发的Julia模块,而且从文档中还不清楚如何调用非Base函数。几年前对此问题进行了一些讨论,但与此同时API似乎已发生变化。任何指针将不胜感激。

1 个答案:

答案 0 :(得分:1)

jl_eval_string("using SomeModule")返回NULL的原因仅仅是因为using SomeModule返回nothing

您可以通过以下方式使用其他模块中的函数:首先导入模块,然后从该Julia模块中将函数对象检索到C中。例如,让我们使用软件包GR及其plot函数。我们可以使用{p>

plot

在这里,我们将jl_eval_string("using GR") // this returns nothing jl_module_t* GR = (jl_module_t *)jl_eval_string("GR") // this returns the module /* get `plot` function */ jl_function_t *plot = jl_get_function(GR, "plot"); 模块作为第一个参数传递给GR。我们可以知道事情将被加载到模块jl_get_function中,并且Main是从plot导出的事实,我们可以使用以下代码片段进行相同的操作。请注意,GR拥有指向模块jl_main_module的指针。

Main

我们还可以使用jl_eval_string("using GR") /* get `plot` function */ jl_function_t *plot = jl_get_function(jl_main_module, "plot"); 的限定名称。

plot

也就是说,这是使用/* get `plot` function */ jl_function_t *plot = jl_get_function(jl_main_module, "GR.plot"); 绘制值数组的完整示例。该示例使用第一种样式来获取函数GR

GR.plot

包括本地文件中的Julia模块并在C中使用它

我不知道本地Julia软件包的确切含义,但是,您可以#include <julia.h> JULIA_DEFINE_FAST_TLS() // only define this once, in an executable (not in a shared library) if you want fast code. #include <stdio.h> int main(int argc, char *argv[]) { /* required: setup the Julia context */ jl_init(); /* create a 1D array of length 100 */ double length = 100; double *existingArray = (double*)malloc(sizeof(double)*length); /* create a *thin wrapper* around our C array */ jl_value_t* array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 1); jl_array_t *x = jl_ptr_to_array_1d(array_type, existingArray, length, 0); /* fill in values */ double *xData = (double*)jl_array_data(x); for (int i = 0; i < length; i++) xData[i] = i * i; /* import `Plots` into `Main` module with `using`*/ jl_eval_string("using GR"); jl_module_t* GR = (jl_module_t *)jl_eval_string("GR");; /* get `plot` function */ jl_function_t *plot = jl_get_function(GR, "plot"); /* create the plot */ jl_value_t* p = jl_call1(plot, (jl_value_t*)x); /* display the plot */ jl_function_t *disp = jl_get_function(jl_base_module, "display"); jl_call1(disp, p); getchar(); /* exit */ jl_atexit_hook(0); return 0; } 您的文件,然后将模块导入这些文件中以执行相同的操作。这是一个示例模块。

include

要包含此文件,您需要使用# Hello.jl module Hello export foo! foo!(x) = (x .*= 2) # multiply entries of x by 2 inplace end 。由于某些原因,嵌入式Julia无法直接访问jl_eval_string("Base.include(Main, \"Hello.jl\")");。您需要改用include

Base.include(Main, "/path/to/file")

这是用C语言编写的完整示例。

jl_eval_string("Base.include(Main, \"Hello.jl\")");
jl_eval_string("using Main.Hello"); // or just '.Hello'
jl_module_t* Hello = (jl_module_t *)jl_eval_string("Main.Hello"); // or just .Hello