简体   繁体   English

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

[英]How do I return a String Array from a C# function to a C++ function calling it?

I'm working with JNI and I have .net library written in C# that I want to pass values from to Java, using C++ and JNI as an intermediary. 我正在使用JNI,我有一个用C#编写的.net库,我希望使用C ++和JNI作为中介将值传递给Java。

I've not worked with C++ in quite some time. 我已经有一段时间没有使用C ++了。 This is what I have for my C# method that I need to pass the return value to the C++ method : 这是我需要将返回值传递给C ++方法的C#方法的功能:

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

That method is being called from the native library I'm writing in C++. 从我用C ++编写的本机库中调用了该方法。 The only problem is, I have no idea how to translate the string array from .net into something readable by C++. 唯一的问题是,我不知道如何将.net中的字符串数组转换为C ++可读的内容。 This is the C++ method I have that would be responsible for returning the value called from the C# .net library : 这是我拥有的C ++方法,负责返回从C#.net库调用的值:

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?
}

So I guess the question is : What does .net return a string array as to C++ when C++ is calling a .net function? 所以我想问题是:当C ++调用.net函数时,.net返回关于C ++的字符串数组是什么?

EDIT 1 : 编辑1:

I was able to get a bit of a clue when I resolved some of the other bugs : When I tried to compile returning a value of char * it gave me this error : 当我解决了其他一些错误时,我可以得到一些线索:当我尝试编译时返回char *的值时,它给了我这个错误:

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

That helps a little but when I tried to use that as the return value, well, it didn't like it very much... So now the question becomes : How do I make System::String __gc * __gc[] into a return type that C++ likes? 这有一点帮助,但是当我尝试使用它作为返回值时,它并不太喜欢...所以现在的问题变成了:如何将System::String __gc * __gc[]变成一个返回C ++喜欢的类型?

EDIT 2: 编辑2:

More progress : So the proper way to format the function header is System::String __gc *<FunctionName>()[] . 更大的进步:所以格式化函数头的正确方法是System::String __gc *<FunctionName>()[] Unfortunately C++ isn't very forgiving and it won't simply let you return that value as a jobjectArray. 不幸的是,C ++并不是很宽容,它不会简单地让您将该值作为jobjectArray返回。 So my next step is going to be grabbing the values from the array and dropping them into a new jobjectArray... 因此,我的下一步将是从数组中获取值并将其放入新的jobjectArray中...

EDIT 3: 编辑3:

So now I'm here : 所以现在我在这里:

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;
}

The error I get is : JNIEnv_::NewStringUTF' : cannot convert parameter 1 from 'System::String __gc *' to 'const char * So now I need to figure out how to convert System::String __gc * into const char * . 我得到的错误是: JNIEnv_::NewStringUTF' : cannot convert parameter 1 from 'System::String __gc *' to 'const char *所以现在我需要弄清楚如何将System::String __gc *转换为const char *

So after a long and arduous trek we have come to our answer. 因此,经过漫长而艰苦的跋涉,我们终于找到了答案。 The resolution to be able to pass an array of strings from a C# function to Java via JNI is thus : 因此,能够通过JNI将字符串数组从C#函数传递给Java的分辨率为:

using namespace System::Runtime::InteropServices; 使用名称空间System :: Runtime :: InteropServices; //<-----NameSpace with a method we need... // <----- 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;
}

I can only hope in the future someone comes across this and is able to make use of it. 我只能希望将来有人遇到这个问题并能够加以利用。

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

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