C++/CLI を使用して Java クライアントを C# に接続していますServiceHost
。これまでのところ、これを使用してサービスにアクセスし、クライアント
をClient
定義しています。ServiceHost
JNIEXPORT jstring JNICALL Java_Client_GetData(JNIEnv *env, jobject, jstring xml)
{
try
{
Client ^client = gcnew Client();
return env->NewStringUTF(marshal_as<string>(
client->GetData(marshal_as<String^>(env->GetStringUTFChars(xml, 0))
)).c_str());
}
catch(Exception^ ex)
{
Console::WriteLine(ex->ToString());
}
return NULL;
}
それはうまくいきますが、呼び出しごとに接続を開いたり閉じたりするのではなく、同じオブジェクトで呼び出しを行うために、オブジェクトを Java 側に格納できるようにしたいと考えています。Client
これについて決定的なものを見つけるのは困難でした。出来ますか?
マークされた回答ごとに思いついた解決策は次のとおりです。
JNIEXPORT jlong JNICALL Java_Client_Create(JNIEnv* env, jobject obj)
{
try
{
Client^ client = gcnew Client();
client->Connect();
long result = reinterpret_cast<long>(GCHandle::ToIntPtr(GCHandle::Alloc(client)).ToPointer());
return result;
}
catch(Exception^ ex)
{
Console::WriteLine(ex->ToString());
}
return NULL;
}
その long を Java に格納することで、それをjlong
パラメーターとしてGetData
メソッドに渡すことができます。
JNIEXPORT jstring JNICALL Java_Client_GetData(JNIEnv *env, jobject, jlong ptr, jstring xml)
{
try
{
GCHandle h = GCHandle::FromIntPtr(IntPtr(reinterpret_cast<void*>(ptr)));
Client^ client = safe_cast<Client^>(h.Target);
const char* xmlChars = (const char*)env->GetStringChars(xml, 0);
string xmlString(xmlChars);
env->ReleaseStringChars(xml, (const jchar*)xmlChars);
const char* data = marshal_as<string>(client->GetData(
marshal_as<String^>(xmlString)
)).c_str();
int length = strlen(data);
return env->NewString((const jchar*)data, length);
}
catch(EndpointNotFoundException^)
{
return NULL;
}
catch(Exception^ ex)
{
Console::WriteLine(ex->ToString());
}
return NULL;
}
あとは、別の JNI メソッドを作成してClient
接続を閉じ、オブジェクトを破棄するだけです。