通过抽签,我自己管理了一个位置。 我完全可以与COM物体连接,并掌握检索各种应用信息的方法。
My problem is now with Sink Objects (trying to get the application to send me events).
As far as I can tell, everything is returning a good return code, but the Invoke on the Sink Class is never called. Whats worse, if a Event was suppose to be called, Releasing the COM object that told it to start sending events, hangs the application. If I end the application advising it of the sink but not making it fire any events, the application doesn t hang.
我尝试了各种方法和汇编者。 他们都得出同样的结果。 然而,如果我在贾瓦以外实际应用(exe)时使用同样的法典,那么所有事情都会被罚款,事件都是通过Sink 反对发射的。 因此,我真的因为 picture的错误而丧生。
这里是我迄今为止的法典:
PcommControl.h (My Wrapper for Control the COMs)
initConnectionManagerEvents: creates a new sink object and advises the COM of it. RegisterStartEvent tells the COM to start sending messages to the sink objects.
移除ConnectionManager 活动:不了解和删除所有思考对象。 UnregisterStartEvent告诉COM公司停止向汇物体发送电文。
jobject PcommControl::initConnectionManagerEvents(jobject sinkType) {
if (!initConnectionManager())
return NULL;
if (autConnectionManagerPoint == NULL) {
autConnectionManagerPoint = getConnectionPoint(autConnectionManager,
DIID_IStartEvent);
if (autConnectionManagerPoint == NULL)
return NULL;
}
ConnectionSink *conSinkC = new ConnectionSink(jvm, sinkType);
if (!conSinkC->isInitialized()) {
delete conSinkC;
return NULL;
}
if (!conSinkC->Advise(autConnectionManagerPoint)) {
#ifdef DEBUG
printf("PcommControl: failed to advise ConnectionManagerEvent
");
#endif
delete conSinkC;
return NULL;
}
#ifdef DEBUG
printf("PcommControl: ConnectionManagerEvent> %ld
", conSinkC->getCookie());
#endif
ConnectionSink *temp = connectionManagerEvents.put(
(long) conSinkC->getCookie(), conSinkC);
if (temp) {
temp->Release();
}
if (connectionManagerEvents.getSize() == 1) {
#ifdef DEBUG
printf("PcommControl: Registering ConnectionManagerEvent
");
#endif
HRESULT hresult = autConnectionManager->RegisterStartEvent();
if (!SUCCEEDED(hresult)) {
#ifdef DEBUG
printf("Failed to get RegisterStartEvent
");
#endif
// TODO
}
}
return conSinkC->getJavaObjectConnection();
}
void PcommControl::removeConnectionManagerEvents() {
ConnectionSink *connectionSink;
if ((autConnectionManager) && (!safeUnload)) {
#ifdef DEBUG
printf("PcommControl: Unregistering ConnectionManagerEvent
");
#endif
// TODO: seems to cause hanging issues for Java
HRESULT hresult = autConnectionManager->UnregisterStartEvent();
if (!SUCCEEDED(hresult)) {
#ifdef DEBUG
printf("Failed to UnregisterStartEvent
");
#endif
}
}
while ((connectionSink = connectionManagerEvents.removeHead()) != NULL) {
if (!safeUnload) {
#ifdef DEBUG
printf("PcommControl: releasing a connection manager event
");
#endif
connectionSink->Unadvise();
#ifdef DEBUG
printf("PcommControl: start release
");
#endif
connectionSink->Release();
}
}
#ifdef DEBUG
printf("PcommControl: done releasing ConnectionManager events
");
#endif
}
JNIEventSink.h (My Sink Interface for all JNI Sinks)
#ifndef JNIEVENTSINK_H_
#define JNIEVENTSINK_H_
#include <jni.h>
#include <OCIdl.h>
#define FARFAR FAR* FAR*
class JNIEventSink: public IDispatch {
protected:
private:
bool initialized;
bool deconstructor;
DWORD referenceCount;
JavaVM *jvm;
jobject javaObjectConnection;
DWORD cookie;
IConnectionPoint *point;
static jclass javaLangClass;
static jmethodID javaLangClassNewInstance;
void init(JavaVM *javaVM, jobject sinkType) {
initialized = false;
deconstructor = false;
referenceCount = 0;
jvm = javaVM;
javaObjectConnection = NULL;
cookie = 0;
AddRef();
// create Java sink class from sinkType
// if (javaVM) {
// JNIEnv *env;
// javaVM->AttachCurrentThread((void **) &env, NULL);
// if (env == NULL) {
//#ifdef DEBUG
// printf("JNIEventSink: java environment not found!
");
//#endif
// return;
// }
//
// if (javaLangClass == NULL) {
// javaLangClass = NULL;
// javaLangClassNewInstance = NULL;
//
// javaLangClass = env->FindClass("java/lang/Class");
// if (javaLangClass == NULL) {
//#ifdef DEBUG
// printf("JNIEventSink: javaLangClass not found!
");
//#endif
// return;
// }
// javaLangClassNewInstance = env->GetMethodID(javaLangClass,
// "newInstance", "()Ljava/lang/Object;");
// if (javaLangClassNewInstance == NULL) {
//#ifdef DEBUG
// printf(
// "JNIEventSink: javaLangClass NewInstance not found!
");
//#endif
// return;
// }
// }
//
// javaObjectConnection = env->CallObjectMethod(sinkType,
// javaLangClassNewInstance);
// if (javaObjectConnection == NULL) {
//#ifdef DEBUG
// printf(
// "JNIEventSink: Failed to create new Connection Object!
");
//#endif
// return;
// }
// }
initialized = true;
}
public:
bool test;
JNIEventSink(JavaVM *javaVM, jobject sinkType) {
#ifdef DEBUG
printf("JNIEventSink: constructor
");
#endif
init(javaVM, sinkType);
test = false;
}
virtual ~JNIEventSink() {
#ifdef DEBUG
printf("JNIEventSink: deconstructor
");
if (test)
printf("YESYESYESYESYESYESYESYES
");
#endif
deconstructor = true;
//
// if (point != NULL)
// Unadvise();
//
// if (referenceCount > 0)
// Release();
}
bool isInitialized() {
return initialized;
}
bool Advise(IConnectionPoint *point) {
#ifdef DEBUG
printf("JNIEventSink: Start Advise
");
#endif
this->point = point;
this->point->AddRef();
HRESULT hresult = point->Advise(this, &cookie);
// TODO set cookie to java class
#ifdef DEBUG
printf("JNIEventSink: Advise End
");
if (!SUCCEEDED(hresult))
printf("JNIEventSink: failed
");
#endif
return SUCCEEDED(hresult);
}
bool Unadvise() {
#ifdef DEBUG
printf("JNIEventSink: Start Unadvise
");
#endif
if (point == NULL)
return true;
IConnectionPoint *point = this->point;
this->point = NULL;
HRESULT hresult = point->Unadvise(cookie);
point->Release();
#ifdef DEBUG
printf("JNIEventSink: Unadvise End
");
if (!SUCCEEDED(hresult))
printf("JNIEventSink: failed
");
#endif
return SUCCEEDED(hresult);
}
DWORD getCookie() {
return cookie;
}
jobject getJavaObjectConnection() {
return javaObjectConnection;
}
ULONG
STDMETHODCALLTYPE AddRef() {
#ifdef DEBUG
printf("JNIEventSink: Add Ref %ld,%ld,%ld
", (long) this, cookie,
referenceCount);
#endif
referenceCount++;
return referenceCount;
}
ULONG
STDMETHODCALLTYPE Release() {
#ifdef DEBUG
printf("JNIEventSink: Start Release %ld,%ld,%ld
", (long) this,
cookie, referenceCount);
#endif
if (referenceCount == 0) {
#ifdef DEBUG
printf("0 ref
");
#endif
return 0;
}
referenceCount--;
long temp = referenceCount;
if ((temp == 0) && (!deconstructor)) {
#ifdef DEBUG
printf("JNIEventSink: deleting
");
#endif
delete this;
}
return temp;
}
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,
void **ppvObject) {
#ifdef DEBUG
printf("JNIEventSink: QueryInterface %ld,%ld
", (long) this, cookie);
#endif
if (iid == IID_IUnknown) {
*ppvObject = (IUnknown *) this;
} else if (iid == IID_IDispatch) {
*ppvObject = (IDispatch *) this;
} else {
*ppvObject = (void *) this;
}
((IUnknown *) (*ppvObject))->AddRef();
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo) {
#ifdef DEBUG
printf("JNIEventSink: GetTypeInfoCount %ld,%ld
", (long) this, cookie);
#endif
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid,
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) {
#ifdef DEBUG
printf("JNIEventSink: GetIDsOfNames %ld,%ld
", (long) this, cookie);
#endif
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(unsigned int iTInfo,
LCID lcid, ITypeInfo FARFAR ppTInfo) {
#ifdef DEBUG
printf("JNIEventSink: GetTypeInfo %ld,%ld
", (long) this, cookie);
#endif
return E_NOTIMPL;
}
// virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid,
// LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams,
// VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo,
// unsigned int FAR* puArgErr) = 0;
};
jclass JNIEventSink::javaLangClass = NULL;
jmethodID JNIEventSink::javaLangClassNewInstance = NULL;
#endif /* JNIEVENTSINK_H_ */
LinkSink.h (My Implementation of the JNI Sink that is suppose to Rec all Activities from autConnectionManager)
#ifndef CONNECTIONSINK_H_
#define CONNECTIONSINK_H_
#include <jni.h>
#include "PcommInterfaces.h"
#include "..COMJNIEventSink.h"
class ConnectionSink: public JNIEventSink {
private:
public:
ConnectionSink(JavaVM *javaVM, jobject sinkType) :
JNIEventSink(javaVM, sinkType) {
}
virtual ~ConnectionSink() {
#ifdef DEBUG
printf("ConnectionSink: deconstructor
");
#endif
}
// IStartEvent
// future events I want to call
// 1 - void NotifyStartEvent(VARIANT ConnHandle, VARIANT_BOOL bStarted);
// 2 - void NotifyStartError(VARIANT ConnHandle);
// 3 - void NotifyStartStop(int* Reason);
virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams,
VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo,
unsigned int FAR* puArgErr) {
// TODO this seems like it is never called
#ifdef DEBUG
printf("ConnectionSink: Invoke %ld,%ld,%ld
", (long) this,
this->getCookie(), dispIdMember);
#endif
test = true;
return S_OK;
//return E_NOTIMPL;
}
};
#endif /* CONNECTIONSINK_H_ */
Example output when it hangs:
Java_gov_ssa_utils_pcomm_ConnectionManager_registerStartEvents
JNIEventSink: constructor
JNIEventSink: Add Ref 72880304,0,0
JNIEventSink: Start Advise
JNIEventSink: Add Ref 72880304,0,1
JNIEventSink: Advise End
PcommControl: ConnectionManagerEvent> 1
PcommControl: Registering ConnectionManagerEvent
Created and attached sink.
Waiting 10 seconds for user to fire event
Destroying.
Java_gov_ssa_utils_PComm_release
PcommControl: destroying
PcommControl: Unregistering ConnectionManagerEvent
感谢任何帮助。