views:

60

answers:

1

I'm writing a wrapper in .NET (C++/CLI) to be able to use some native C++ Qt code in .NET. How can I map a Qt signal into a managed .NET event, so that when my Qt code fires off a signal, I can bring this forward to the .NET code.

My Managed class defines the event, but if I try to use the normal QObject::connect method to hook up to the signal, it requires a QObject * receiver... I guess I have to do some magic marshalling of some sorts?

A: 

Define normal unmanaged Qt event handler. From this handler, raise managed event.

Edit: if you have previous experience in Qt, you know how to handle Qt signals in unmanaged class. Don't try to make this class managed. Instead of this, write C++/CLI wrapper which contains this QObject-derived class.

Edit 2. Create C++/CLI Console application, call it test1, and add the following code to it:

test1.cpp:

#include "stdafx.h"
#include "ManagedClass.h"

using namespace System;

int main(array ^args)
{
    ManagedClass^ c = gcnew ManagedClass();
    c->Test();

    return 0;
}

ManagedClass.h:

#pragma once

class UnmanagedClass;

// Wrapper
ref class ManagedClass
{
public:
    ManagedClass(void);
    ~ManagedClass();
    !ManagedClass();
    void Test();
    void Callback();

private:
    UnmanagedClass* m_pUnmanagedClass;
};

ManagedClass.cpp:

#include "StdAfx.h"
#include "ManagedClass.h"
#include "UnmanagedClass.h"

ManagedClass::ManagedClass(void)
{
    m_pUnmanagedClass = new UnmanagedClass(this);
}

ManagedClass::~ManagedClass()
{
    this->!ManagedClass();
    GC::SuppressFinalize(this);
}

ManagedClass::!ManagedClass()
{
    if ( m_pUnmanagedClass )
    {
        delete m_pUnmanagedClass;
        m_pUnmanagedClass = NULL;
    }
}


void ManagedClass::Test()
{
    m_pUnmanagedClass->Test();
}

void ManagedClass::Callback()
{
    Console::WriteLine(L"This text is printed from managed wrapper function, called from unmanaged class.");
    Console::WriteLine(L"Here you can raise managed event for .NET client.");
    Console::WriteLine(L"Let's say that UnmanagedClass is QObject-derived, and this funcstion");
    Console::WriteLine(L"is called from UnmanagedClass Qt event handler - this is what you need.");
}

UnmanagedClass.h:

#pragma once

#include 
using namespace System;


ref class ManagedClass;

// Wrapped native class
class UnmanagedClass
{
public:
    UnmanagedClass(ManagedClass^ pWrapper);
    ~UnmanagedClass(void);
    void Test();

private:
    gcroot m_pWrapper;
};

UnmanagedClass.cpp:

#include "StdAfx.h"
#include "UnmanagedClass.h"
#include "ManagedClass.h"

UnmanagedClass::UnmanagedClass(ManagedClass^ pWrapper)
{
    m_pWrapper = pWrapper;
}

UnmanagedClass::~UnmanagedClass(void)
{
}

void UnmanagedClass::Test()
{
    m_pWrapper->Callback();
}

This gives you idea how unmanaged class and managed wrapper can play together. If you know Qt programming and know how to raise .NET event from ref C++/CLI class, this is enough to accomplish your task.

Alex Farber
Do I create a new QObject inherited class for this purpose? If not, how do I connect my managed class to the Qt signal? QObject::connect only accepts QObject* ... Do you have a small code example?
notbo
Sorry for being stupid here.. should I create another Qt class to connect to the signal, and from its slot raise the managed event somehow? Should this Qt class be part of my C++/CLI project? Cause this one needs to be moc'ed I guess? And how would it know about the managed event and raise it? Seems like you have done this before.. do you have some code to share that shows how to do this?
notbo
Thanks! I have now solved the issue.. For other people that might read this later.. Have the unmanaged class inherit from QObject, so that it can connect to the Qt signal. Remember that you need to MOC the unmanaged class as well (custom build step on the involved file in your C++/CLI project).
notbo