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;
}