一、支持
通过mono, c++调用c#的可以传入的参数类型支持类型有:
1、基本数据类型(bool float double enum...)
2、引用类型
3、结构体类型
4、类对象
5、数组
6、指针数组
7、字符串
mono环境搭建方法,参考上一篇博客
二、示例
下面代码演示,各种类型调用的方法:
mian.cpp和test_case.h在c++工程中
TestSharp.cs在c#dll中
main.cpp
#include
#include
#include
#include
#include
#include "TestCase.h"
MonoDomain* domain;
int main()
{
// Program.cs所编译dll所在的位置
const char* managed_binary_path = "G:/Project/Mono/MonoTest/MonoDll/bin/Debug/netcoreapp3.1/MonoDll.dll";
//获取应用域
domain = mono_jit_init("Test");
//加载程序集ManagedLibrary.dll
MonoAssembly* assembly = mono_domain_assembly_open(domain, managed_binary_path);
MonoImage* image = mono_assembly_get_image(assembly);
// =====================================================准备调用
//获取MonoClass,类似于反射
MonoClass* main_class = mono_class_from_name(image, "MonoDll", "TestCSharp");
// 创建类对象
MonoObject* mono_object = mono_object_new(domain, main_class);
TestCase1(mono_object);
TestCase2(mono_object);
TestCase3(mono_object);
TestCase4(mono_object, image);
TestCase5(mono_object, image);
TestCase6(mono_object);
//释放应用域
mono_jit_cleanup(domain);
return 0;
}
test_case.h
#pragma once
#include
#include
#include
#include
#include
#include
#include
struct struct_test
{
float f = 3.5;
double d = 6.555;
MonoString* s;
};
class class_test
{
float f = 90.5;
double d = 110.452;
MonoString* s;
};
struct struct_test1
{
float f;
double d;
};
void TestCase1(MonoObject *mono_object)
{
MonoDomain *domain = mono_object_get_domain(mono_object);
MonoClass* mono_class = mono_object_get_class(mono_object);
//获取要调用的MonoMethodDesc,主要调用过程
MonoMethodDesc* entry_point_method_desc = mono_method_desc_new(":.ctr()", false);
MonoMethod* entry_point_method = mono_method_desc_search_in_class(entry_point_method_desc, mono_class);
mono_method_desc_free(entry_point_method_desc);
if (entry_point_method != nullptr)
{
mono_runtime_invoke(entry_point_method, mono_object, nullptr, nullptr);
}
}
// 基础参数类型调用
void TestCase2(MonoObject* mono_object)
{
MonoClass* mono_class = mono_object_get_class(mono_object);
bool e = false;
float f = 93.4f;
double d = 8.3f;
int i = 6;
void* p[4];
p[0] = &e;
p[1] = &f;
p[2] = &d;
p[3] = &i;
MonoMethod * mono_method = mono_class_get_method_from_name(mono_class, "TestBaseTypeParameter", 4);
if (mono_method != nullptr)
{
mono_runtime_invoke(mono_method, mono_object, p, nullptr);
}
}
void TestCase3(MonoObject* mono_object)
{
MonoClass* mono_class = mono_object_get_class(mono_object);
bool e = false;
float f = 93.4;
double d = 8.3f;
int i = 6;
void* p[4];
p[0] = &e;
p[1] = &f;
p[2] = &d;
p[3] = &i;
MonoMethod* mono_method = mono_class_get_method_from_name(mono_class, "TestBaseTypeRefParameter", 4);
if (mono_method != nullptr)
{
mono_runtime_invoke(mono_method, mono_object, p, nullptr);
std::cout << e << " " << f << " " << d << " " << i << std::endl;
}
}
// 数组
void TestCase4(MonoObject* mono_object, MonoImage *image)
{
MonoClass* mono_class = mono_object_get_class(mono_object);
MonoDomain* domain = mono_object_get_domain(mono_object);
//获取MonoClass,类似于反射
MonoClass* main_class1 = mono_class_from_name(image, "MonoDll", "struct_test1");
std::vector array_s;
struct_test s_t;
array_s.push_back(s_t);
array_s.push_back(s_t);
array_s.push_back(s_t);
array_s.push_back(s_t);
MonoArray * mono_array = mono_array_new(domain, main_class1, array_s.size());
for (int i = 0; i < array_s.size(); i++)
{
mono_array_set(mono_array, struct_test, i, array_s[i]);
}
MonoMethod* mono_method = mono_class_get_method_from_name(mono_class, "TestArrayParameter", 1);
void* p[1];
p[0] = mono_array;
if (mono_method != nullptr)
{
mono_runtime_invoke(mono_method, mono_object, p, nullptr);
}
}
// 对象参数
void TestCase5(MonoObject* mono_object, MonoImage* image)
{
MonoClass* mono_class = mono_object_get_class(mono_object);
MonoDomain* domain = mono_object_get_domain(mono_object);
//获取MonoClass,类似于反射
MonoClass* main_class1 = mono_class_from_name(image, "MonoDll", "class_test");
MonoObject* mono_object1 = mono_object_new(domain, main_class1);
MonoClassField* mono_class_field = mono_class_get_field_from_name(main_class1, "f");
float f = 3;
mono_field_set_value(mono_object1, mono_class_field, &f);
mono_class_field = mono_class_get_field_from_name(main_class1, "d");
double d = 6.44;
mono_field_set_value(mono_object1, mono_class_field, &d);
MonoMethod* mono_method = mono_class_get_method_from_name(mono_class, "TestClassParameter", 1);
void* p[1];
p[0] = mono_object1;
if (mono_method != nullptr)
{
mono_runtime_invoke(mono_method, mono_object, p, nullptr);
}
}
void TestCase6(MonoObject* mono_object)
{
MonoClass* mono_class = mono_object_get_class(mono_object);
struct_test1 e[4];
void* p[1];
p[0] = &e;
MonoMethod* mono_method = mono_class_get_method_from_name(mono_class, "TestPointParameter", 1);
if (mono_method != nullptr)
{
mono_runtime_invoke(mono_method, mono_object, p, nullptr);
}
}
TestSharp.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace MonoDll
{
public struct struct_test
{
public float f;
public double d;
public string s;
}
public struct struct_test1
{
public float f;
public double d;
}
public class class_test
{
public float f;
public double d;
public string s;
}
public class TestCSharp
{
// 构造函数
public TestCSharp()
{
Console.WriteLine("TestCSharp");
}
// 基础参数类型调用
public void TestBaseTypeParameter( bool e, float f, double d, int i)
{
Console.WriteLine("TestBaseTypeParameter {0} {1} {2} {3}", e, f, d, i);
}
// 基础参数引用调用
public void TestBaseTypeRefParameter(ref bool e, ref float f, ref double d, ref int i)
{
Console.WriteLine("TestBaseTypeRefParameter {0} {1} {2} {3}", e, f, d, i);
}
// 数组
public void TestArrayParameter(struct_test[] ss)
{
for (int i = 0; i < ss.Length; i++)
{
var s = ss[i];
Console.WriteLine("ArrayParameter index {0}", i);
Console.WriteLine("ArrayParameter {0} {1} {2}", s.f, s.d, s.s);
}
}
// 对象参数
public void TestClassParameter(class_test c)
{
Console.WriteLine("TestClassParameter {0} {1} {2}", c.f, c.d, c.s);
}
// 传入地址的数组
unsafe public void TestPointParameter(IntPtr ptr, int count)
{
void *p = ptr.ToPointer();
struct_test1* p1 = (struct_test1*)p;
for (int i = 0; i < count; i++)
{
Console.WriteLine("TestPointParameter {0} {1}", p1[i].d, p1[i].f);
}
}
}
}