我正在使用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;
}
这很好,但我希望能够将我的Client
对象存储在Java端,以便使用相同的对象进行调用,而不是为每个调用打开和关闭连接。
很难找到关于此的确定性。有可能吗?
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;
}
通过在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
连接并处理该对象。
答案 0 :(得分:1)
更改本机方法以返回jlong,并返回新创建的Client对象指针的地址。
创建第二个清理内存的本机方法,该方法接受上一次调用时的商店jlong,将其强制转换为Client指针,然后将其删除。
请参阅This answer for the correct syntax on handle to pointer conversion