English 中文(简体)
JNI: Sink Object not Firing, Releases forced
原标题:JNI: Sink Object not Firing, Releases freezing
  • 时间:2011-11-08 16:56:42
  •  标签:
  • object
  • com

我正试图通过一个COM公司为这一窗口申请建立一个称为个人通信的JNI包裹。 反对:

通过抽签,我自己管理了一个位置。 我完全可以与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

感谢任何帮助。

最佳回答

我提出了一个问题。

www.un.org/Depts/DGACM/index_spanish.htm 产生 object子的透镜()也需要利用窗户的功能()抽取直线信号。 GetMessage

正因为如此,被迫害的窗口工作正确,它已经为创建的窗口配备了信息泵。 我在被点名时在ink子中打断点,并看着 st痕,就说明了这一点。 盖特马斯蒂奇是我守则的痕迹中的第一个。

在这种情况下,我认为,为什么GetMessage是答案,因为我认为,COM码正在呼吁邮政局通知我,已经发生了一场清醒事件,GetMessage审视了这些信息,以及他们自己掌握的一些知识。

<>PS>/strong>: 通知我说,这造成了思考。 如果你在一线read子中 create起ink子,在另一边带电泵,你会收到COM关于ink子的信息,但是,由于这一read子在其空间没有装上COM。 因此,从来就不要求 object子。

So Java could access the same COM everywhere, I made the 2nd thread control everything about the COM, and any native methods that were called redirect the request to the that thread. So no matter what thread Java is running in, it will always have access to the same COM without having to reload everything.

问题回答

暂无回答




相关问题
How can i add a button to all windows explorer instances?

I am trying to add a button to one of the existing tool bars in any windows explorer instance. After much research i figured out that BHO (browser helper objects) are the best way to hook to ...

Hunting memory leaks

I m finding leaked heap blocks by using the following command in WinDbg !heap –l With each leaked heap block I get, I m running to following to get the stack trace. !heap -p -a leakedheapblock The ...

Why use CComBSTR instead of just passing a WCHAR*?

I m new to COM. What exactly is the advantage of replacing: L"String" with CComBSTR(L"String") I can see a changelist in the COM part of my .NET application where all strings are replaced in this ...

IThumbnailProvider and IInitializeWithItem

I am trying to develop an IThumbnailProvider for use in Windows 7. Since this particular thumbnail would also be dependant on some other files in the same directory, I need to use something other than ...

Getting a byte array from out of process C++ COM to C#

What s the best way to get a chunk of memory (i.e. void*) from a COM server to C#? We have been using an IStream (using CreateStreamOnHGlobal) and passing that back, which worked. However when we ...

COM Basic links

folks can you provide me the tutorial link or .pdf for learning basic COM?. i do google it.. still i recommend answers of stackoverflow so please pass me.. Thanks

热门标签