Reputation: 106
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
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