所以我能够在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,所以这里可能有一些显而易见的东西......
谢谢!
答案 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);