1

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接続を閉じ、オブジェクトを破棄するだけです。

4

1 に答える 1