Step 3: Implement the marshaler class

PowerBuilder Native Interface

Step 3: Implement the marshaler class

The marshaler class must implement the InvokeRemoteMethod function. It also needs to provide a Destroy function and get the handle of the module. This is the declaration:

#include <jni.h>
#include <pbext.h>

class JavaMarshaler : public IPBX_Marshaler
{
  jobject      d_jobject;
  pbproxyObject  d_pbobject;

public:
  JavaMarshaler(JNIEnv* env, pbproxyObject pbobj, jobject ejbobj);
  ~JavaMarshaler();

  virtual PBXRESULT InvokeRemoteMethod
    (
    IPB_Session*  session,
    pbproxyObject  obj,
    LPCSTR      method_name,
    PBCallInfo*    ci
    );

  virtual pbulong  GetModuleHandle();

  virtual void Destroy();
};

The InvokeRemoteMethod function calls Java functions through JNI. This is the implementation in JavaMarshaler.cpp:

#include "JavaMarshaler.h"
#include "JMethod.h"
#include "JavaVMWrapper.h"

extern pbulong g_dll_hModule;

pbulong  JavaMarshaler::GetModuleHandle()
{
  return g_dll_hModule;
}
//****************************************************
//  JavaMarshaler
//****************************************************
JavaMarshaler::JavaMarshaler
(
  JNIEnv*      env,
  pbproxyObject  pbobj,
  jobject      ejbobj
)
:  d_jobject(env->NewGlobalRef(ejbobj)),
     d_pbobject(pbobj)
{
}

JavaMarshaler::~JavaMarshaler()
{
  JNIEnv* env = JavaVMWrapper::instance()->getEnv();

  if (d_jobject != NULL && env != NULL)
    env->DeleteGlobalRef(d_jobject);
}

PBXRESULT JavaMarshaler::InvokeRemoteMethod
(
  IPB_Session*   session,
  pbproxyObject  obj,
  LPCSTR         szMethodDesc,
  PBCallInfo*    ci
)
{
  static char* eFailedToInvokeJavaMethod  =
    "Failed to invoke the Java method.";

  JNIEnv* env = JavaVMWrapper::instance()->getEnv();
  JMethod method(this, szMethodDesc);

  try
  {
    if (d_jobject != NULL)
    {
      method.invoke(session, env, d_jobject, ci);
      if (env->ExceptionCheck() == JNI_TRUE)
      {
        string error(eFailedToInvokeJavaMethod);
        error += "\n";
        // Throw exception here

        return PBX_E_INVALID_ARGUMENT;
      }
    }
  }
  catch(...)
  {
  }

  return PBX_OK;
}

void JavaMarshaler::Destroy()
{
  delete this;
}