在C#WinForm中调用julia函数及在C#中传递参数到julia函数的使用示例

news/2025/3/15 16:00:29/

特别声明:未经允许,请勿转载! 

https://discourse.juliacn.com/t/topic/7189https://discourse.juliacn.com/t/topic/7189我在julia中国社区已提交了文章的最后部分未解决问题,大家后续可以在该链接中跟踪问题的回答进度。

好几年前就接触过julia,当时觉得并不好用,

如今julia版本已经来到了1.8.5版本,但是仍觉得它的生态还是不够好,很多问题都找不到答案。

我记录下当前的使用情况,在C#调用julia这块,结合前人的使用示例,我认为我这篇文章应该属于C#操作julia是最全的了。

在C#调用julia方面,目前已实现了如何使用以下函数(还有很多API接口函数可以在julia.h和jlapi.c中找到,但是要全部都会使用又是另一回事了):

jl_call1
jl_call2
jl_call3
jl_init__threading
jl_eval_string
jl_unbox_float64
jl_box_float64
jl_atexit_hook

此前搜索到前辈们留下的一个问题,

http://cn.voidcc.com/question/p-dhvlazdi-ux.htmlhttp://cn.voidcc.com/question/p-dhvlazdi-ux.html该链接是前人未结案的文章,至少我是这么认为。

我发现他的第1个和第2个结果是错误的,我把

public static extern IntPtr jl_box_float64(float value);

改为(float => double)

public static extern IntPtr jl_box_float64(double value);

得到的结果就正常了。

但是以下遇到的问题仍未解决.
julia脚本如下:

module JuliaClassexport calculatefunction calculate(a::Float64, b::Float64)::Float64return a * pi + b^2endfunction calcMore(a, b)return ones(a, b)::Array{Float64,2};endfunction calc3par(a, b, c)return (a + b + c)::Float64;endfunction calcArray(a::Array{Float64,1})return (a[0] + a[1] + a[2])::Float64;end
end


C#脚本如下:

//====================================================================[DllImport("kernel32.dll")]static extern bool SetDllDirectory(string lpPathName);[DllImport("libjulia.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]public static extern void jl_init__threading(string path);[DllImport("libjulia.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]public static extern IntPtr jl_eval_string(string input);[DllImport("libjulia.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]public static extern IntPtr jl_box_float64(double value);[DllImport("libjulia.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]public static extern double jl_unbox_float64(IntPtr value);[DllImport("libjulia.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]public static extern IntPtr jl_get_global(IntPtr func, string name);[DllImport("libjulia.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]public static extern IntPtr jl_call(IntPtr func, IntPtr[] v1, int v2);[DllImport("libjulia.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]public static extern IntPtr jl_call1(IntPtr func, IntPtr v1);[DllImport("libjulia.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]public static extern IntPtr jl_call2(IntPtr func, IntPtr v1, IntPtr v2);[DllImport("libjulia.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]public static extern IntPtr jl_call3(IntPtr func, IntPtr v1, IntPtr v2, IntPtr v3);[DllImport("libjulia.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]public static extern void jl_atexit_hook(int a);//====================================================================private void button_CsCallJulia_Click(object sender, EventArgs e){///加载julia环境路径string julia_home_dir = Application.StartupPath + "\\Julia-1.8.5\\bin";//我的WinForm是32位的,所以安装的是32位的juliaSetDllDirectory(julia_home_dir);jl_init__threading(julia_home_dir);///加载julia脚本路径string jl_ScriptPath = "./JuliaScript/test_julia.jl";string jl_include = "include(\"" + jl_ScriptPath + "\")";///等效于julia>include("./JuliaScript/test_julia.jl")IntPtr jl_DoString = jl_eval_string(jl_include);///执行julia脚本中JuliaClass模块的calculate函数IntPtr jl_ret = jl_eval_string("JuliaClass.calculate(2.0,4.0)");///julia函数返回值给C#中的IntPtr类型double cs_val = jl_unbox_float64(jl_ret);///julia拆箱转换为C#的double数据类型Console.WriteLine("result1={0}", cs_val);///C#传递参数给juliaIntPtr jl_function = jl_eval_string("JuliaClass.calculate");IntPtr jl_par1 = jl_box_float64(3.0);///C#参数1装箱IntPtr jl_par2 = jl_box_float64(4.0);///C#参数2装箱jl_ret = jl_call2(jl_function, jl_par1, jl_par2);///传入到julia指定模块中的函数,以及参数,注:jl_call2只能传递1个函数和2个参数cs_val = jl_unbox_float64(jl_ret);///julia拆箱转换为C#的double数据类型Console.WriteLine("result2={0}", cs_val);jl_function = jl_eval_string("JuliaClass.calc3par");jl_par1 = jl_box_float64(12.0);jl_par2 = jl_box_float64(13.0);IntPtr jl_par3 = jl_box_float64(14.0);jl_ret = jl_call3(jl_function, jl_par1, jl_par2, jl_par3);cs_val = jl_unbox_float64(jl_ret);Console.WriteLine("result3={0}", cs_val);}


问题就是:
1.我不知道如何在C#里通过jl_call传递一个数组到julia中的calcArray函数,
我尝试->

            jl_function = jl_eval_string("JuliaClass.calcMore");IntPtr[] jl_par = new IntPtr[3] { (IntPtr)11, (IntPtr)12, (IntPtr)13 };jl_ret = jl_call(jl_function, jl_par, 3);Console.WriteLine("result4={0}", jl_ret);


运行这段代码它报错如下:

result1=22.2831853071796
result2=25.4247779607694
result3=39

引发的异常:“System.AccessViolationException”(位于 RobotTestingAPP.exe 中)
“System.AccessViolationException”类型的未经处理的异常在 RobotTestingAPP.exe 中发生 
尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

因此我不知道在C#中如何正确使用jl_call,搜索全网找不到答案!
2.如何在C#中使用jl_base_module等函数,如果是用C++调用,则是很方便,但我对C++并不了解。


http://www.ppmy.cn/news/68447.html

相关文章

JSP在线考试系统的设计与实现(源代码+论文)

在线考试系统旨在实现考试的无纸化管理,基于计算机和网络技术进行在线考试系统的使用,既方便校方对考试的管理,也方便了考生,尤其适合考生分布广,不易集中的远程教育。 基于远程教育的推广和在线考试需求的增加&#…

Android13 xml配置文件乱码问题解决

Android13 xml配置文件乱码问题解决 文章目录 前言原因解决方法 前言 Android13 中发现cat 某个的配置文件 是 乱码! 这个跟普通的中文乱码问题不同,因为拉到电脑查看也是乱码! Android 查看 Sttings Global 属性情况: cat /da…

区分有状态和无状态组件

有状态组件和无状态组件是 React 中两种不同的组件类型,它们在处理数据和实现逻辑的方式上有所不同。 有状态组件(Stateful Components): 有状态组件是指具有内部状态(state)的组件,可以通过 s…

带你一文了解分布式事务~

书接上文,如果不明白我之前写了什么的话,可以看下之前我文章: 序列化隔离级别在数据库系统中可以解决其他隔离级别无法处理的问题,这是因为它提供了最高的隔离性和数据一致性。 目前大多数提供可序列化的数据库都使用了三种技术…

wincc利用VBS脚本读取SQL数据库中的配方数值

一、建立wincc项目变量 二、创建SQL数据库 1、单击connect(连接)按钮,注意服务器的名称必须是XXX\WINCC的格式 2、然后右击Databases(数据库)——单击New Databases(新建数据库) 在弹出的对话框…

发挥数据潜能,为在金融服务行业进行创新做好准备

发挥数据潜能,为在金融服务行业进行创新做好准备 为何选择 NetApp 的金融服务? 作为云专家,我们将确保始终适时适地提供财务数据,以推动转型。我们将消除数据孤岛,提供实时的市场就绪分析,借助经验证的 AI…

进阶自定义类型——结构体,枚举,联合

本章重点: 1.结构体 1.1 结构体类型的声明 1.2 结构的自引用 1.3 结构体变量的定义和初始化 1.4 结构体内存对齐 1.5 结构体传参 1.6 结构体实现位段(位段的填充&可移植性) 2.枚举 2.1 枚举类型的定义 2.2 枚举的优点 2.3 枚举的使用 3.联合 3.1 联合类…

MYSQL02高级_目录结构、默认数据库、表文件、系统独立表空间

文章目录 ①. MySQL目录结构②. 查看默认数据库③. MYSQL5.7和8表文件③. 系统、独立表空间 ①. MySQL目录结构 ①. 如何查看关联mysql目录 [rootmysql8 ~]# find / -name mysql /var/lib/mysql /var/lib/mysql/mysql /etc/selinux/targeted/tmp/modules/100/mysql /etc/seli…