Problem using QT Code in Haxe

159 views
Skip to first unread message

ZSoft

unread,
Feb 12, 2016, 7:00:52 AM2/12/16
to Haxe
I have some QT bluetooth code that I want to use in my Haxe project.
So I created a native extension (ndll) and use it in haxe. This has worked fine for me in the past with other non-QT code.

The extension builds fine, but as soon as I build the haxe app that uses the extension I get:
Error : Could not load module test@test_sample_method__1


I have narrowed the problem down to these reproducible steps:

- Generate a basic extension: openfl create extension Test

- Modify the generated test.cpp like so:
#include "Utils.h"
#include <QtBluetooth/QLowEnergyDescriptor>
//#include <QtBluetooth/QBluetoothUuid>

namespace test {
    int SampleMethod(int inputValue) {
        //QBluetoothUuid id;
        QLowEnergyDescriptor desc;

        return inputValue * 100;  
    }   
}

- Modify Build.xml like so:
<xml>
    <include name="${HXCPP}/build-tool/BuildCommon.xml"/>
    <files id="common">
        <compilerflag value="-Iinclude"/>
        <compilerflag value="-I/opt/Qt5.5.1/5.5/gcc/include/QtBluetooth"/>
        <compilerflag value="-I/opt/Qt5.5.1/5.5/gcc/include"/>
        <compilerflag value="-I/opt/Qt5.5.1/5.5/gcc/include/QtCore"/>

        <file name="common/ExternalInterface.cpp"/>
        <file name="common/test.cpp"/>
    </files>
    <set name="SLIBEXT" value=".lib" if="windows"/>
    <set name="SLIBEXT" value=".a" unless="windows"/>
    <set name="SLIBEXT" value=".so" if="webos"/>
    <set name="DEBUGEXTRA" value="-debug" if="fulldebug" />
    <target id="NDLL" output="${LIBPREFIX}test${MSVC_LIB_VERSION}${DEBUGEXTRA}${LIBEXTRA}" tool="linker" toolid="${STD_MODULE_LINK}">
        <lib name="/opt/Qt5.5.1/5.5/gcc/lib/libQt5Core.so"/>
        <lib name="/opt/Qt5.5.1/5.5/gcc/lib/libQt5Bluetooth.so"/>

        <outdir name="../ndll/${BINDIR}"/>
        <ext value=".ndll" if="windows || mac || linux"/>
        <files id="common"/>
    </target>
    <target id="default">
        <target id="NDLL"/>
    </target>
</xml>

- then register the extension with haxelib:
haxelib dev test PATH_TO_THE_EXTENSION_ROOT

- then use the extension in the haxe app by adding to the project xml:
<haxelib name="test"/>
- and in the code use the function like
test.sampleMethod(16);
- then build using openfl test linux
(I'm currently working in 32-bit Linux Debian)

The error will show up.

Now, if you comment out QLowEnergyDescriptor, and uncomment QBluetoothUuid, and repeat the process. It will work fine.#

What is the difference here? How do I fix it?

Thanks! :)

Hugh

unread,
Feb 14, 2016, 9:02:27 PM2/14/16
to Haxe
It could be that then you make this call, your NDLL depends on libQt5Bluetooth.so or similar, which it can't find at load time, causing your ndll to not load.
From memory, you can set the environment variable
LD_LOAD_DEBUG to "files"
The this will print some stuff while it is trying to load (not 100% sure of details to the variable)
You can also set HXCPP_LOAD_DEBUG to "1" and get some more info.

Hugh

ZSoft

unread,
Feb 15, 2016, 9:55:23 AM2/15/16
to Haxe
Thank you very much, super useful!
My QT installation was messed up.
(It was LD_DEBUG="files" btw.)

Cambiata

unread,
Feb 16, 2016, 6:22:39 AM2/16/16
to Haxe
@ZSoft: Cool. Do you use QT for UI also?

Message has been deleted

ZSoft

unread,
Feb 16, 2016, 7:09:27 AM2/16/16
to Haxe
No, Haxe is my main. I use QT for Bluetooth Low Energy only.

Which isn't very straightforward as you need to create a thread that runs a QCoreApplication in order for signals/slots etc. to work. But it does work.

Here's the basic setup for that, copied from Stackoverflow (a link was not allowed in the post..):

class Q_DECL_EXPORT SharedLibrary :public QObject    
{
Q_OBJECT
public:
    SharedLibrary();

private slots:

    void onStarted();

private:
    static int argc = 1;
    static char * argv[] = {"SharedLibrary", NULL};
    static QCoreApplication * app = NULL;
    static QThread * thread = NULL;
};


SharedLibrary::SharedLibrary()
{
    if (thread == NULL)
    {
        thread = new QThread();
        connect(thread, SIGNAL(started()), this, SLOT(onStarted()), Qt::DirectConnection);
        thread->start();
    }
}
SharedLibrary::onStarted()
{
   if (QCoreApplication::instance() == NULL)
   {
       app = new QCoreApplication(argc, argv);
       app->exec();
   }
}  

Reply all
Reply to author
Forward
0 new messages