首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从C++调用本地Julia包

从C++调用本地Julia包
EN

Stack Overflow用户
提问于 2019-05-03 20:43:07
回答 1查看 1.2K关注 1票数 4

Julia文档展示了如何从C(例如sqrt)调用Base Julia函数的示例,我已经成功地复制了它。我真正感兴趣的是调用本地开发的Julia模块,而从文档中完全不清楚如何调用非基础函数。几年前有一些关于这个问题的讨论线程,但API似乎在此期间发生了变化。如有任何建议,我们将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-07 15:12:26

jl_eval_string("using SomeModule")返回NULL的原因很简单,因为using SomeModule返回nothing

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

代码语言:javascript
运行
复制
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的指针。

代码语言:javascript
运行
复制
jl_eval_string("using GR")

/* get `plot` function */
jl_function_t *plot = jl_get_function(jl_main_module, "plot");

我们也可以使用plot的限定名。

代码语言:javascript
运行
复制
/* get `plot` function */
jl_function_t *plot = jl_get_function(jl_main_module, "GR.plot");

也就是说,下面是使用GR绘制一组值的完整示例。该示例使用第一个样式来获取函数GR.plot

代码语言:javascript
运行
复制
#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;
}

包含来自本地文件的Julia模块,并在C++中使用它

我不知道本地Julia包到底是什么意思,但是,您可以include您的文件,然后导入这些文件中的模块来做同样的事情。这是一个示例模块。

代码语言:javascript
运行
复制
# Hello.jl
module Hello
export foo!

foo!(x) = (x .*= 2) # multiply entries of x by 2 inplace

end

要包含此文件,您需要使用jl_eval_string("Base.include(Main, \"Hello.jl\")");。由于某些原因,嵌入式Julia不能直接访问include。您需要改用Base.include(Main, "/path/to/file")

代码语言:javascript
运行
复制
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

下面是用C编写的完整示例。

代码语言:javascript
运行
复制
#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;
}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55970064

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档