0

ネイティブ dll で作成されたスレッドからマネージ ラッパーへのコールバックを作成したいのですが、スレッドを正常に作成し、Qt.s フレームワークのシグナルとスロットを介して呼び出しを行いました。

アンマネージド DLL とマネージド DLL の間で別のスレッドからメイン スレッドへのコールバックを作成するにはどうすればよいですか? アンマネージドは QT c++ で行われ、マネージドは VS c++ で行われます。

アンマネージ dll: main.cpp

typedef void (__stdcall * processCallback)(char*, int, int);
Thread* thread;
EXTEXPORT_VOID initdll(processCallback callback)
{
    /* Init MainThread - Runs eventloop */
    thread = new Thread(callback);
    thread ->start();
}

thread.h - run メソッド。ここでコールバックを作成しますが、マネージド DLL でコールバックを作成したメイン スレッドではなく、新しいスレッドでコールバックが続行されます。なんで?

void run() {
    callback("Testing callback", 0, 0);
    exec();
}

このコールバックは、現在実行中のスレッドではなく、メイン スレッドに対して行う必要があります。

マネージ dll

/* From unmanaged to managed c++ */
[UnmanagedFunctionPointerAttribute(CallingConvention::StdCall)] 
public delegate void UnmanagedCallbackDelegate(char*, int, int);

typedef void (__stdcall * typeCallback)(char*, int, int); //Same def as in Unm. dll
public ref class cDLLThreadWrapper
{
    [DllImport("cDLL.dll", CallingConvention=CallingConvention::StdCall)] 
    static void initdll(typeCallback);

public:
    typeCallback callbackNative;
    UnmanagedCallbackDelegate^ m_CallbackDelegate;

    cDLLThreadWrapper()
    {

    }
    void init()
    {
        m_CallbackDelegate = gcnew UnmanagedCallbackDelegate(this, &cDLLThreadWrapper::UnhandledCallback);
        IntPtr ptr = Marshal::GetFunctionPointerForDelegate(m_CallbackDelegate);
        callbackNative = static_cast<typeCallback>(ptr.ToPointer());

        initdll(callbackNative);
    }
            void UnhandledCallback(char* data, int x, int y)
    {
        String^ callStr = gcnew String(data);
                    //AppDomain.GetCurrentThreadId())
        //I get here but the thread is wrong, it should be the main thread
                    //which called the initdll function from this wrapper.
    }
}

私が言ったように、コールバックは機能しますが、何らかの理由で間違ったスレッドでそれを取得します.コールバックはスレッド1からのものであるべきではありません->メインスレッド?

これは非常に単純化された例ですが、特定の質問は、コールバックが新しく作成されたスレッドからメイン スレッドに移動せず、新しく作成されたスレッドに留まる理由です。どこが間違っていると思いますか?どんな助けでも大歓迎です!

4

1 に答える 1

1

コールバックを直接呼び出しとして実行していますが、何が驚きでしょうか? Qt で実行callback(...)すると、新しいスレッドでも実行され、続行されます。これは、シグナルスロット接続をQt::DirectConnectiontype で宣言するのと同じです。Qt は巧妙でQt::QueuedConnection、呼び出し元スレッドとターゲット スレッドが異なる場合に舞台裏で実行します。しかし、それが自動的に機能するためには、ソースを として宣言しsignal、ターゲットを として宣言し、ターゲットを として宣言し、Qt 固有のイベント ループを実行slotする必要があります。QThreadマネージ C++ で「いくつかの」イベント ループが実行されていますが、Qt はそこに投稿する方法と内容がわかりません。間違いなくQObject.NET C++ はそれを理解できません。Qt マジックは Qt 内部でのみ機能します。イベントがどのように具体的に .NET C++ にポストされるかを調べ、それを行うように Qt コードに教える必要があります。私は .NET の専門家ではありませんが、次のものが役に立ちます。

Managed C++ (C++/CLI) で Qt シグナルをイベントにマップする方法

于 2012-08-15T14:46:31.917 に答える