我正在尝试使用mono使用某些c#(或f#)代码扩展用Linux编写的c语言库。
从c调用c#的简单示例看起来很简单:
//c# code, compiled with mcs -t:library Ex1.cs
public static class Ex1 {
public class Inner {
public static void someAction(int i) {
System.Console.WriteLine("some action with " + i);
}
}
}
//c code, compiled with gcc ex1.c $(pkg-config --cflags --libs mono-2)
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
int main()
{
MonoDomain *domain = mono_jit_init("Ex1.dll");
MonoAssembly *assembly = mono_domain_assembly_open(domain, "Ex1.dll");
MonoImage *image = mono_assembly_get_image(assembly);
MonoClass *class_ptr = mono_class_from_name(image, "", "Ex1/Inner");
MonoMethod *class_method = mono_class_get_method_from_name_flags(
class_ptr, "someAction", 1, 0);
void *args[1];
int value = 42;
args[0] = &value;
mono_runtime_invoke(class_method, NULL, args, NULL);
mono_jit_cleanup(domain);
return 0;
}
正在运行./a.out,我们看到了c#库的输出。
但是有可能在c端实现接口或至少在c#中定义的委托吗?
例如:
//c# compiled mcs -t:library Ex2.cs
public static class Ex2 {
public interface MyInterface {
void someAction(int i);
}
public delegate void MyDelegate(int i);
public static class Inner {
static public void someAction1(MyInterface iface, int value) {
iface.someAction(value);
}
static public void someAction2(MyDelegate d, int value) {
d(value);
}
}
}
//c compiled with gcc ex2.c $(pkg-config --cflags --libs mono-2)
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
int main()
{
MonoDomain *domain = mono_jit_init("Ex2.dll");
MonoAssembly *assembly = mono_domain_assembly_open(domain, "Ex2.dll");
MonoImage *image = mono_assembly_get_image(assembly);
MonoClass *class_ptr = mono_class_from_name(image, "", "Ex2/Inner");
MonoMethod *class_method1 = mono_class_get_method_from_name_flags(
class_ptr, "someAction1", 2, 0);
MonoMethod *class_method2 = mono_class_get_method_from_name_flags(
class_ptr, "someAction2", 2, 0);
void *args1[2];
int value1 = 42;
args1[0] = NULL;//how to correctly initialize this?
args1[1] = &value1;
mono_runtime_invoke(class_method1, NULL, args1, NULL);
void *args2[2];
int value2 = 42;
args2[0] = NULL; //or this?
args2[1] = &value2;
mono_runtime_invoke(class_method2, NULL, args2, NULL);
mono_jit_cleanup(domain);
return 0;
}
谢谢。