Julia 文档显示了如何从 C(例如sqrt
)调用 Base Julia 函数的示例,我已经成功地复制了这些函数。我真正感兴趣的是调用本地开发的 Julia 模块,从文档中完全不清楚如何调用非 Base 函数。几年前有一些关于这个问题的讨论线程,但 API 似乎在此期间发生了变化。任何指针将不胜感激。
jl_eval_string("using SomeModule")
返回的原因NULL
很简单,因为using SomeModule
返回nothing
。
您可以通过首先导入模块,然后将该 Julia 模块中的函数对象检索到 C 中来使用其他模块中的函数。例如,让我们使用包GR
及其plot
函数。我们可以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");
Run Code Online (Sandbox Code Playgroud)
在这里,我们将GR
module 作为第一个参数传递给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");
Run Code Online (Sandbox Code Playgroud)
我们也可以使用plot
s 限定名。
/* get `plot` function */
jl_function_t *plot = jl_get_function(jl_main_module, "GR.plot");
Run Code Online (Sandbox Code Playgroud)
也就是说,这里是使用GR
. 该示例使用第一种样式来获取函数GR.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");
Run Code Online (Sandbox Code Playgroud)
我不知道本地 Julia 包的确切含义,但是,您可以 include
将文件导入这些文件中的模块来执行相同的操作。这是一个示例模块。
# Hello.jl
module Hello
export foo!
foo!(x) = (x .*= 2) # multiply entries of x by 2 inplace
end
Run Code Online (Sandbox Code Playgroud)
要包含此文件,您需要使用jl_eval_string("Base.include(Main, \"Hello.jl\")");
. 出于某种原因,嵌入式 Julia 无法include
直接访问。你需要Base.include(Main, "/path/to/file")
改用。
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
Run Code Online (Sandbox Code Playgroud)
这是 C 语言中的完整示例。
#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);
JL_GC_PUSH1(&x);
/* fill in values */
double *xData = (double*)jl_array_data(x);
for (int i = 0; i < length; i++)
xData[i] = i * i;
/* import `Hello` module from file Hello.jl */
jl_eval_string("Base.include(Main, \"Hello.jl\")");
jl_eval_string("using Main.Hello");
jl_module_t* Hello = (jl_module_t *)jl_eval_string("Main.Hello");
/* get `foo!` function */
jl_function_t *foo = jl_get_function(Hello, "foo!");
/* call the function */
jl_call1(foo, (jl_value_t*)x);
/* print new values of x */
for (int i = 0; i < length; i++)
printf("%.1f ", xData[i]);
printf("\n");
JL_GC_POP();
getchar();
/* exit */
jl_atexit_hook(0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)