繁体   English   中英

嵌入式Mono:将数组从C#DLL返回/复制到C ++

[英]Embedded mono: return / copy an array from C# DLL to C++

我有一个C ++应用程序,应该使用DLL中的某些功能,该DLL是用C#编写并使用mono编译的。 我已经想出了如何使这些C#函数从我的C ++代码运行,但是仍然很难理解如何引用通常是已知大小的数组的C#结果。

我的C ++代码如下所示:

MonoDomain* domain = mono_jit_init("CSharpDLLname.dll");
MonoAssembly* assembly = mono_domain_assembly_open(domain, "CSharpDLLname.dll");
MonoImage* image = mono_assembly_get_image(assembly);
MonoClass* klass = mono_class_from_name(image, "MyNamespace", "MyClass");
MonoObject* object = mono_object_new(domain, klass);
// call ctor
mono_runtime_object_init(object);

MonoMethodDesc* mdesc = mono_method_desc_new(":test(single[])", false);
MonoMethod* method = mono_method_desc_search_in_class(mdesc, klass);

void* args[1];
args[0] = &something;

// call function with provided args
mono_runtime_invoke(method, object, args, NULL);

// shutdown the runtime
mono_jit_cleanup (domain);

这是我在C#DLL中调用的函数的类型:

public static float[] tester(float[] arr)
{
    // ... do things to arr
    // create an array of known size
    float[] barr = new float[3];
    barr[0] = 1;
    barr[1] = 2;
    barr[2] = 3;
    // return it as result
    return barr;
}

问题是如何从C ++代码中获取barr的指针或副本?

我尝试使用

MonoObject* returnObj = mono_runtime_invoke(method, object, args, NULL);
float* result = (float*)mono_object_unbox (returnObj);

但这导致

在object.c:6493上声明,条件'obj-> vtable-> klass-> valuetype'不满足。 ...在执行本机代码时得到了SIGABRT。 这通常表示Mono运行时或应用程序使用的本机库之一发生致命错误。

如果我返回单个值,例如public static float tester() ,则它可以工作,并且我能够读取结果。 现在,我希望能够读取一个数组。

一个简单的C +函数示例(返回数组的C#函数)会很棒。 或者,如果mono_runtime_invoke()mono_object_unbox()不是正确的方法(我是C#和mono的初学者),那么很高兴知道如何正确进行操作-再次感谢基本示例。

我找不到有关如何返回或复制整个数组的答案,但想出了另一种方法。 由于获取blittable类型的工作原理,而不是返回整个数组的函数,因此我习惯了获取数组的每个元素。 例如:

C#代码:

private float[] m_array; // the array we want to copy to our C++ code 
private int m_numElements; // length of the array

public static int getLength()
{
    return m_numElements; 
}

public static float[] getArray() // this will not work
{
    return m_array;
}

public static float getArrayElement(int index) // we will use this instead!
{
    return m_array[index];
}

C ++代码中的用法:

MonoObject* lengthObj = mono_runtime_invoke(methodGetLength, object, NULL, NULL);
int length = *(int*)mono_object_unbox(lengthObj);

// now allocate the array where you will cope the result to
std::vector<float> array; // or could also be float[length]
array.resize(length);
for (int i=0; i<length; ++i){
    void* args[1];
    args[0] = &i;
    // obtain the next element with index i
    MonoObject* elementObj = mono_runtime_invoke(methodGetElement, object, args, NULL);
    // copy the result to our array
    array[i] = *(float*)mono_object_unbox(elementObj);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM