Get a string from a c++ library with a java wrapper around it

Good Evening,

I have a c++ library file where I am trying to get a string value from but not by return.

.cpp file
JNIEXPORT jint JNICALL Java_MyNamespace_ClassName_FunctionName
(JNIEnv *env, jclass obj, jstring returnString)
{
returnString = env->NewStringUTF("returnStringValue");
return 1;
}

In my Solution I have:

.cs File
namespace myNamespace
{
[DllImport("FolderName", EntryPoint = "Java_MyNamespace_ClassName_FunctionName")]
private static extern int FunctionName(IntPtr env, IntPtr thiz, IntPtr returnString);

        void test_function()
        {
            IntPtr j = new IntPtr();

            int status = FunctionName(JNIEnv.Handle, IntPtr.Zero, j);

            string ss = j.ToString();
            //Where I am expecting ss to be containing "returnStringValue".
        }
    }

Best Answer

  • MariusTuguleaMariusTugulea ✭✭ US ✭✭
    Accepted Answer

    Thanks @BillHolmes

    We created a byte array
    byte[] x = new byte[120];

    Allocated that memory and copied it

    System.Runtime.InteropServices.Marshal.AllocHGlobal()
    System.Runtime.InteropServices.Marshal.Copy()
    

    And then converted using:
    System.Text.Encoding.UTF8.GetString()

Answers

  • BillHolmesBillHolmes Xamurai USXamarin Team Xamurai

    Try...

    To get a string from an IntPtr (that points to a JavaString) you would use the following.

    JNIEnv.GetString (j, JniHandleOwnership.TransferLocalRef);

    Not sure this will work in your case as you are passing null in the j variable to Java_MyNamespace_ClassName_FunctionName . You may have to instantiate the string in C# and pass that to the function. Something like this.

    IntPtr native_p0 = JNIEnv.NewString ("Hello");
    int status = FunctionName(JNIEnv.Handle, IntPtr.Zero, native_p0);
    var ret = JNIEnv.GetString (status, JniHandleOwnership.TransferLocalRef);
    JNIEnv.DeleteLocalRef (native_p0);  // Not sure about this or the JniHandleOwnership.TransferLocalRef
    
    

    I am not the expert but it may get you headed in the right direction.

    Do you have to invoke into a JNI style method? Can you simply expose a C call and avoid java strings? Also if this is a real java object have you looked into creating a [Java binding library}(https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/)?

  • MariusTuguleaMariusTugulea ✭✭ USMember ✭✭
    Accepted Answer

    Thanks @BillHolmes

    We created a byte array
    byte[] x = new byte[120];

    Allocated that memory and copied it

    System.Runtime.InteropServices.Marshal.AllocHGlobal()
    System.Runtime.InteropServices.Marshal.Copy()
    

    And then converted using:
    System.Text.Encoding.UTF8.GetString()

Sign In or Register to comment.