如何将字符串数组从C#函数返回到调用它的C ++函数?

时间:2014-11-20 20:53:02

标签: java c# c++ arrays

我正在使用JNI,我使用C#编写的.net库,我希望将值传递给Java,使用C ++和JNI作为中介。

我在很长一段时间内都没有使用过C ++。这就是我需要将返回值传递给C ++方法的C#方法:

public string[] getSystemFingerPrint(){ //<---- This method is called from a C++ class.
    /* Code Body */
    return FingerPrint._fingerprint;
}

从我用C ++编写的本机库调用该方法。唯一的问题是,我不知道如何将字符串数组从.net转换为C ++可读的东西。这是我负责返回从C#.net库调用的值的C ++方法:

FingerPrintC __gc *t;
FingerPrintC() {
    t = new FingerPrint();
}
.
.
.
char[] getSystemFingerPrint(){ //<----I know that's the wrong return value.
    return t->getSystemFingerPrint(); //<----What will .net return the string array as here?
}

所以我想问题是:当C ++调用.net函数时,.net会为C ++返回一个字符串数组吗?

编辑1:

当我解决了一些其他错误时,我能够得到一些线索:当我尝试编译返回char *的值时,它给了我这个错误:

error C2440: 'return' : cannot convert from 'System::String __gc * __gc[]' to 'char *'

这有点帮助,但当我尝试将其用作返回值时,嗯,它不太喜欢它......所以现在问题变成:如何使System::String __gc * __gc[]成为返回值C ++喜欢的类型?

编辑2:

更多进展:因此格式化函数头的正确方法是System::String __gc *<FunctionName>()[]。不幸的是,C ++不是很宽容,它不会简单地让你将该值作为jobjectArray返回。所以我的下一步是从数组中获取值并将它们放入一个新的jobjectArray ......

编辑3:

所以现在我在这里:

JNIEXPORT jobjectArray JNICALL Java_RegistrationControl_GetSystemFingerPrint (JNIEnv *jn, jobject jobj){
    FingerPrintC* t = new FingerPrintC();
    System::String __gc * t2[] = t->GetSystemFingerPrint();
    jobjectArray ret =
        (jobjectArray)jn->NewObjectArray(
            6,
            jn->FindClass("java/lang/String"),
            jn->NewStringUTF("")
        );
    for (int c = 0; c < 6; c++) jn->SetObjectArrayElement(ret, c, jn->NewStringUTF(t2[c])); //<---- This line fails.
    return ret;
}

我得到的错误是:JNIEnv_::NewStringUTF' : cannot convert parameter 1 from 'System::String __gc *' to 'const char *现在我需要弄清楚如何将System::String __gc *转换为const char *

1 个答案:

答案 0 :(得分:0)

经过漫长而艰苦的艰苦跋涉,我们得到了答案。 因此,能够通过JNI将字符串数组从C#函数传递给Java的解决方案是:

使用命名空间System :: Runtime :: InteropServices; //&lt; ----- NameSpace使用我们需要的方法......

JNIEXPORT jobjectArray JNICALL Java_RegistrationControl_GetSystemFingerPrint (JNIEnv *jn, jobject jobj){ //<----- The Native Function to be called by Java
    System::String __gc * t2[] = FingerPrint::GetSystemFingerPrint(); //<----- The method called from the C# library.
    jobjectArray ret = (jobjectArray)jn->NewObjectArray( //<-----Define the jobjectArray
        6, //<-----Must know exactly how many elements are in the array. This works for me.
        jn->FindClass("java/lang/String"), //<<-----Type of the array.
        jn->NewStringUTF("") //<-----Initialize each array value, I guess?
    );
    for (int c = 0; c < 6; c++){
        const char *i = (char*)(void*)Marshal::StringToHGlobalAnsi(t2[c]); //<-----Transform the "string" into something that the JNI method can tolerate.
        jn->SetObjectArrayElement(ret, c, jn->NewStringUTF(i)); //<-----jn->NewStringUTF(i) transforms the string into something Java can tolerate. This line transforms the transformed string and adds it to the array to be returned.
    }
    return ret;
}

我只能希望将来有人遇到这个并且能够利用它。