所以我已经能够让以下代码在 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 ools 并测试 est.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 工作还很陌生,所以这里可能有一些对其他人来说显而易见的东西......
谢谢!
为 C 库制作 C# 包装器是一个复杂的过程。我可以提供一些提示,但强烈建议您仔细阅读。
pinvoke 圣经是 adam nathans 的书 http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X
但首先 - 对于不透明句柄,请使用 IntPtr 而不是 object
[DllImport("libjulia.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr jl_get_function(IntPtr m,string name);