JNIEXPORT jobject JNICALL Java_com4j_Native_invokeDispatch( JNIEnv* env, jclass _, jlong pComObject, jint dispId, jint flag, jobjectArray args) { DISPPARAMS params; DISPID dispIdPropertyPut = DISPID_PROPERTYPUT; params.cArgs = env->GetArrayLength(args); params.cNamedArgs = 0; params.rgdispidNamedArgs = NULL; VARIANT* p = new VARIANT[params.cArgs]; params.rgvarg = p; for(unsigned int i=0; i<params.cArgs; i++ ) { // we have to store the params in reverse order! (scm) int destIndex = params.cArgs - 1 - i; VARIANT* v = convertToVariant(env,env->GetObjectArrayElement(args,i)); if(v==NULL) { // VariantInit(&p[i]); p[destIndex] = vtMissing; } else { p[destIndex] = *v; // just transfer the ownership delete v; } } // see MSDN IDispatch::Invoke // "When you use IDispatch::Invoke() with DISPATCH_PROPERTYPUT or DISPATCH_PROPERTYPUTREF, you have to specially // initialize the cNamedArgs and rgdispidNamedArgs elements of your DISPPARAMS structure with the following:" if(flag==DISPATCH_PROPERTYPUT || flag==DISPATCH_PROPERTYPUTREF) { params.cNamedArgs = 1; params.rgdispidNamedArgs = &dispIdPropertyPut; } EXCEPINFO excepInfo; memset(&excepInfo,0,sizeof(EXCEPINFO)); jobject retVal = com4j_Variant_new(env); HRESULT hr = reinterpret_cast<IDispatch*>(pComObject)->Invoke( dispId, IID_NULL, 0, (WORD) flag, ¶ms, com4jVariantToVARIANT(env,retVal), &excepInfo, NULL ); if(FAILED(hr)) { error(env,__FILE__,__LINE__,hr,"Invocation failed: %s",(LPCSTR)_bstr_t(excepInfo.bstrDescription)); } delete p; return retVal; }
STDMETHODIMP CEventReceiver::Invoke( DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pResult, EXCEPINFO* pExcepInfo, UINT* puArgErr ) { AttachThread jniScope(jniModule); JNIEnv* pEnv = jniScope; jobjectArray ar = pEnv->NewObjectArray(pDispParams->cArgs,com4j_Variant,NULL); {// copy arguments into com4j Variant types, since we may later change their types LockedArray<jobject> data(pEnv,ar); int len = pDispParams->cArgs; for( int i=0; i<len; i++ ) { data[len-i-1] = com4j_Variant_new(pEnv); ::VariantCopy(com4jVariantToVARIANT(pEnv,data[len-i-1]), &pDispParams->rgvarg[i]); } } jobject r = com4jEventProxy_invoke(pEnv,eventProxy, (jint)dispid,(jint)wFlags,ar); // check if there was any exception jthrowable t = pEnv->ExceptionOccurred(); if(t!=NULL) { pEnv->ExceptionClear(); if(pExcepInfo!=NULL) { pExcepInfo->wCode = 1000; // Java doesn't have any notion of 'error code' pExcepInfo->wReserved = 0; pExcepInfo->bstrSource = SysAllocString(JString(pEnv,com4jEventProxy_getErrorSource(pEnv,t))); pExcepInfo->bstrDescription = SysAllocString(JString(pEnv,com4jEventProxy_getErrorDetail(pEnv,t))); pExcepInfo->bstrHelpFile = NULL; pExcepInfo->dwHelpContext = 0; pExcepInfo->pvReserved = NULL; pExcepInfo->pfnDeferredFillIn = NULL; pExcepInfo->scode = 0; } return DISP_E_EXCEPTION; } if(r!=NULL && pResult!=NULL) { VARIANT* pSrc = convertToVariant(pEnv,r); ::VariantCopy(pResult,pSrc); ::VariantClear(pSrc); } return S_OK; }
jobject get( JNIEnv* env, VARIANT* v, jclass retType ) { jobject r = com4j_Variant_new(env); ::VariantCopy(com4jVariantToVARIANT(env,r),v); return r; }