【问题标题】:How do I return a String Array from a C# function to a C++ function calling it?如何将字符串数组从 C# 函数返回给调用它的 C++ 函数?
【发布时间】:2014-11-20 20:53:01
【问题描述】:

我正在使用 JNI,我有一个用 C# 编写的 .net 库,我想将值从 Java 传递给 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 *&lt;FunctionName&gt;()[]。不幸的是,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 *。

【问题讨论】:

  • 不回答这个问题,但您是否考虑过使用 IKVM 在 .net 上运行整个应用程序?
  • 不,我不会。这是一次性交易,我需要从应用程序中获得的唯一东西就是这个小小的 .net 文件,用于从底层操作系统获取一些信息。
  • 你试过从 C# 方法返回一个 Byte[] 吗?
  • 这不是一个坏主意,但我确实找到了解决方案。只是现在本地库很无聊,所以我必须弄清楚这一点。完成后,我将上传整个解决方案...

标签: java c# c++ arrays


【解决方案1】:

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

使用命名空间 System::Runtime::InteropServices; //

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

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

【讨论】:

    猜你喜欢
    • 2013-03-25
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 2014-11-06
    • 2014-04-11
    相关资源
    最近更新 更多