Reputation: 8135
I try to call C# code from java application, and this is done through a C++ library. So basically I end up in 03 different types of String:
The problem is I have to convert among them. So my convert codes are:
From C++ to C#
String^ toStringCS(const char *chars){
int len = (int)strlen(chars);
array<unsigned char>^ a = gcnew array<unsigned char>(len);
int i = 0;
while(i<len){
a[i] = chars[i];
i++;
}
return Encoding::UTF8->GetString(a);
}
From C# to C++
char* toStringCPP(String^ P){
pin_ptr<const wchar_t> wch = PtrToStringChars(P);
printf_s("%S\n", wch);
size_t convertedChars = 0;
size_t sizeInBytes = ((P->Length + 1) * 2);
errno_t err = 0;
char *ch = (char *)malloc(sizeInBytes);
return ch;
}
From jstring to C++
jboolean isCopyS1;
const char *c_S1 = env->GetStringUTFChars(s1, &isCopyS1);
But I got error while trying to execute the application. When I disabled the toStringCS method, the program runs normally. Can someone show me what did I do wrong in that method?
And I googled to convert from String^ to jstring but I coudln't find any solution.. Can you suggest me some ways to do it ?
Thank you very much.
Upvotes: 1
Views: 1070
Reputation: 20812
I'm not sure where you are going wrong. You are missing free
, at the least. But I wouldn't go through char *
and certainly not modified UTF-8 (via GetStringUTFChars).
.NET System::String and Java System.String on Windows are both code-unit-counted, sequences of UTF-16LE-encoded Unicode characters.
#include <vcclr.h>
jstring CopyDotNetString(JNIEnv *env, System::String^ value)
{
if (value == nullptr) return 0;
const auto codeunitCount = value->Length;
/* .NET System::Char, C++ std::wchar_t, JNI jchar, and Java char are
all the same size and hold a UTF-16LE code unit. */
const pin_ptr<const wchar_t> buffer = PtrToStringChars(value);
return env->NewString(
reinterpret_cast<const jchar*>(buffer),
codeunitCount);
}
System::String^ GetStringFromJava(JNIEnv *env, jstring value)
{
if (value == 0) return nullptr;
const auto codeunitCount = env->GetStringLength(value);
const auto buffer = env->GetStringChars(value, NULL);
try {
return gcnew System::String(
reinterpret_cast<const wchar_t*>(buffer),
0,
codeunitCount);
}
finally {
env->ReleaseStringChars(value, buffer);
}
}
Upvotes: 3