deepak
deepak

Reputation: 106

Pass a string as argument from C# to callback function in C++

I am writing a C# dll wrapper to wrap a third party C# dll. I also need to expose this as Java methods for which I am using an intermediate C++ layer which wraps my C# dll and provides a JNI mechanism to expose the same using java.

However, I am having an issue in passing string as argument to the callback function when its invoked in C++. Here is the code.

#include "stdafx.h"
#include "JavaInclude.h"
#include <iostream>
#using "Class1.netmodule"
#using <mscorlib.dll>

using namespace std;
using namespace System;

int CSomeClass::MemberFunction(void* someParam)
{
    cout<<"Yaay! Callback"<<endl;
    return 0;
}

static int __clrcall SomeFunction(void* someObject, void* someParam, String^ strArg)
{
    CSomeClass* o = (CSomeClass*)someObject;
    Console::WriteLine(strArg);
    return o->MemberFunction(someParam);
}

JNIEXPORT void JNICALL Java_de_tum_kinect_KinectSpeechInit_initConfig
    (JNIEnv *env, jobject obj)
{
    array<String^>^ strarray = gcnew array<String^>(5);
    for(int i=0; i<5; i++)
            strarray[i] = String::Concat("Number ",i.ToString());

    CSomeClass o;
    void* p = 0;
    CSharp::Function(System::IntPtr(SomeFunction), System::IntPtr(&o), System::IntPtr(p), strarray);
}

Here is my C# class

using System;
using System.Runtime.InteropServices;

public class CSharp
{
    delegate int CFuncDelegate(IntPtr Obj, IntPtr Arg, string strArg);

    public static void Function(IntPtr CFunc, IntPtr Obj, IntPtr Arg, String[] pUnmanagedStringArray)
    {
        CFuncDelegate func = (CFuncDelegate)Marshal.GetDelegateForFunctionPointer(CFunc, typeof(CFuncDelegate));

        for (int i = 0; i < pUnmanagedStringArray.Length; i++)
        {
            Console.WriteLine(pUnmanagedStringArray[i]);
        }
        string strArg = "Test String";
        int rc = func(Obj, Arg, strArg);
    }
}

When I did Console::WriteLine(strArg); in my C++ dll, it just prints a blank string! Would really appreciate if anyone can help me as I am pretty new to all this.

Thanks, Deepak

Upvotes: 3

Views: 2251

Answers (1)

Adam
Adam

Reputation: 16199

The most likely issue is that C++ expects ANSI strings where as C# creates Unicodes ones.

So if you replace with this

delegate int CFuncDelegate(IntPtr Obj, IntPtr Arg, [MarshalAs (UnmanagedType.LPSTR)] string strArg); 

You can check out more information here: http://msdn.microsoft.com/en-us/library/s9ts558h

Upvotes: 3

Related Questions