www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Binding Qt API with templated containers

reply Eldar Insafutdinov <e.insafutdinov gmail.com> writes:
Hello everybody.
I started working on the QtD API part that deals with containers. And I need
your advice. There are 2 possible implementations that I consider. First one is
how it is done in QtJambi and I suspect that many other Qt bindings follow it.

// C++ part of the wrapper
// binding QList<QObject *> QObject::children() const
extern "C" Q_DECL_EXPORT jobject JNICALL
QTJAMBI_FUNCTION_PREFIX(Java_com_trolltech_qt_core_QObject__1_1qt_1children__J)
(JNIEnv *__jni_env,
 jobject,
 jlong __this_nativeId)
{
    QtJambiShell_QObject *__qt_this = (QtJambiShell_QObject *)
qtjambi_from_jlong(__this_nativeId);
    
    // ------calling the function itself
    const QList<QObject* >&  __qt_return_value = __qt_this->children();

    // ------ iterating through the result and populating newly created Java
container via JNI
    // ------ with converted values
    jobject __java_return_value = qtjambi_arraylist_new(__jni_env,
__qt_return_value.size());
    QList<QObject* > ::const_iterator __qt_return_value_end_it =
__qt_return_value.constEnd();
    for (QList<QObject* > ::const_iterator __qt_return_value_it =
__qt_return_value.constBegin(); __qt_return_value_it !=
__qt_return_value_end_it; ++__qt_return_value_it) {
        QObject*  __qt_tmp = *__qt_return_value_it;
        jobject __java_tmp = qtjambi_from_qobject(__jni_env, (QObject *)
__qt_tmp, "QObject", "com/trolltech/qt/core/");
        qtjambi_collection_add(__jni_env, __java_return_value, __java_tmp);
    }

    return __java_return_value;
}

JNI code is a bit messy but I tried to explain the idea. In our case we will
create a D array and fill it with marshalled values. That's relatively easy to
implement. But most of people I talked about this to don't like it, because it
is slow. I personally didn't write a lot of Qt code yet and I don't know if
calling methods dealing with containers is going to be intensive or not.
People want to directly bind to QVector and QList. I have now idea how to do
this, because they are templated types and therefore you have to bind to every
template instantiation. Is it possible to recreate them using struct in D and
use it natively? I think people here have experience with STL (don't think Qt
containers bring lots of new things, except a different API style probably).
Apr 08 2009
parent Eldar Insafutdinov <e.insafutdinov gmail.com> writes:
Eldar Insafutdinov Wrote:

 Hello everybody.
 I started working on the QtD API part that deals with containers. And I need
your advice. There are 2 possible implementations that I consider. First one is
how it is done in QtJambi and I suspect that many other Qt bindings follow it.
 
 // C++ part of the wrapper
 // binding QList<QObject *> QObject::children() const
 extern "C" Q_DECL_EXPORT jobject JNICALL
QTJAMBI_FUNCTION_PREFIX(Java_com_trolltech_qt_core_QObject__1_1qt_1children__J)
 (JNIEnv *__jni_env,
  jobject,
  jlong __this_nativeId)
 {
     QtJambiShell_QObject *__qt_this = (QtJambiShell_QObject *)
qtjambi_from_jlong(__this_nativeId);
     
     // ------calling the function itself
     const QList<QObject* >&  __qt_return_value = __qt_this->children();
 
     // ------ iterating through the result and populating newly created Java
container via JNI
     // ------ with converted values
     jobject __java_return_value = qtjambi_arraylist_new(__jni_env,
__qt_return_value.size());
     QList<QObject* > ::const_iterator __qt_return_value_end_it =
__qt_return_value.constEnd();
     for (QList<QObject* > ::const_iterator __qt_return_value_it =
__qt_return_value.constBegin(); __qt_return_value_it !=
__qt_return_value_end_it; ++__qt_return_value_it) {
         QObject*  __qt_tmp = *__qt_return_value_it;
         jobject __java_tmp = qtjambi_from_qobject(__jni_env, (QObject *)
__qt_tmp, "QObject", "com/trolltech/qt/core/");
         qtjambi_collection_add(__jni_env, __java_return_value, __java_tmp);
     }
 
     return __java_return_value;
 }
 
 JNI code is a bit messy but I tried to explain the idea. In our case we will
create a D array and fill it with marshalled values. That's relatively easy to
implement. But most of people I talked about this to don't like it, because it
is slow. I personally didn't write a lot of Qt code yet and I don't know if
calling methods dealing with containers is going to be intensive or not.
 People want to directly bind to QVector and QList. I have now idea how to do
this, because they are templated types and therefore you have to bind to every
template instantiation. Is it possible to recreate them using struct in D and
use it natively? I think people here have experience with STL (don't think Qt
containers bring lots of new things, except a different API style probably).

Max Samukha suggested a nice idea that we can wrap each instantiation separately(not extremely many of them). And that's actually the case in C# bindings. I will try to investigate how they work.
Apr 08 2009