将Julia嵌入C#中 - 传递和返回arugments

时间:2016-03-14 18:12:49

标签: c# julia embedding

所以我能够在Windows 10上的Visual Studio中正常运行以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("libjulia.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void jl_init(string julia_home_dir);

        [DllImport("libjulia.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void jl_eval_string(string str);

        static void Main(string[] args)
        {

            jl_init(@"C:\Julia-0.4.3\bin");

            jl_eval_string("push!(LOAD_PATH, \"c:/development/tools and testing/\")");
            jl_eval_string("using test");

            jl_eval_string("TestFunc()");

            Console.ReadLine();
        }
    }
}

并且 - 此程序调用c:\ development \ tools和testing \ test.jl,其中包含以下Julia代码:

module test

println("Loading the Module")

export TestFunc, Func2

function TestFunc()

    println("In the function")

end

function Func1()

    println("This function returns 4")

    return 4

end

end

它将以下内容写入控制台:

加载模块

在函数中

然后在退出前等待输入。

但是,这使用jl_eval_string函数来调用事物,声明它不会返回任何内容。我希望能够使用jl_get_function,然后使用jl_call0函数调用一个特定的函数,然后让julia代码返回给我一些东西(一旦我可以使这个工作,那么就可以前进到使用jl_call1传递一个参数 - 但现在一步一步。)我认为问题是这些函数返回/接受jl_function_t和jl_value_t的数据类型,这在C#中没有为我定义?

这样的事情:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("libjulia.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void jl_init(string julia_home_dir);

        [DllImport("libjulia.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void jl_eval_string(string str);

        [DllImport("libjulia.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern object jl_get_function(object m,string name);

        [DllImport("libjulia.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern object jl_call0(object m);

        static void Main(string[] args)
        {
            // Pass

            jl_init(@"C:\Julia-0.4.3\bin");

            jl_eval_string("push!(LOAD_PATH, \"c:/development/tools and testing/\")");
            jl_eval_string("using test");

            jl_eval_string("TestFunc()");

            object funcptr = jl_get_function("test", "Func1");

            object ans = jl_call0(funcptr);

            Console.ReadLine();
        }
    }
}

当我运行此程序时,我得到以下内容: 未处理的异常:System.Runtime.InteropServices.MarshalDirectiveException:PInvoke限制:无法返回变体。    在ConsoleApplication1.Program.jl_get_function(对象m,字符串名称)    在ConsoleApplication1.Program.Main(String [] args)

供参考 - 讨论这些功能here

我对C#很陌生,并且正在使用dll,所以这里可能有一些显而易见的东西......

谢谢!

1 个答案:

答案 0 :(得分:0)

为c库制作c#包装器是一个复杂的过程。我可以提供一些提示,但强烈建议阅读它。

pinvoke圣经是adam nathans的书http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X

但是一开始 - 对于不透明句柄,使用IntPtr而不是对象

 [DllImport("libjulia.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr jl_get_function(IntPtr m,string name);