tags:

views:

469

answers:

5

I have a LabVIEW 8.6 program that is using a DLL written in Qt; the DLL listens to a TCP port for incoming messages and updates some internal data. My LabVIEW program calls into the DLL occasionally to read the internal data. The DLL works perfectly (i.e., receives data from the TCP port) with another Qt program. However, it does not work at all with my LabVIEW program.

I've attached a debugger to the DLL and can see calls from LabVIEW going into it -- my function for getting the internal data is being called and I can step through it. The code that gets the data from the TCP is never called though; it looks like the signal for incoming data on the TCP port is never triggered.

I know this sounds like a Qt issue but the DLL works perfectly with another Qt program. Unfortunately, it fails miserably with LabVIEW.

One theory:

  • The event loop is not running when LabVIEW calls the DLL

    • In the Qt DLL's run() function, I call socket->waitForDisconnected(). Perhaps the DLL is not processing incoming events because the event loop is not running? If I call exec() to start the event loop, LabVIEW crashes (LabVIEW 8.6 Development System has encountered a problem and needs to close."):
    AppName: labview.exe     AppVer: 8.6.0.4001     ModName: qtcored4.dll
    ModVer: 4.5.1.0     Offset: 001af21a
  • Perhaps when I call the DLL from another Qt program, that program's event loop is allowing for the TCP signal to be seen by the DLL. Unfortunately, kicking off the event loop in the DLL takes down LabVIEW.

Any thoughts on how to keep signals running in the DLL when LabVIEW is the calling program?

EDIT Debug trace of the exec() call:

QThread::exec() -> eventLoop.exec() -> if (qApp->thread() == thread())

in the call to 

QObject::thread() { 
   return d_func()->threadData->thread;
}

The macro Q_DECLARE_PRIVATE(QObject), the second call, triggers the crash.

EDIT 17 Aug 2009: Status update

After two days of trying various ways to get this to work I decided to implement a TCP listener directly in LabVIEW. My LabVIEW application sends data out via the DLL and receives data in via TCP. All is working well.


This question was cross-posted on http://forums.ni.com/ni/board/message?board.id=170&thread.id=431779

A: 

Can you debug through exec() to see where it crashes LabVIEW?

You can also set debugging the maximum in LabVIEW in the configuration page for the Call Library Node. LabVIEW is finicky with DLLs. It may be easier to run the DLL as a service (write a service that runs the event loop), and then have LabVIEW call a DLL that retrieves the data from the service.

CookieOfFortune
Original question updated with the trace.
dwj
Hmmm... I wonder if it tries to create a thread in the LabVIEW process, that would almost definitely crash LabVIEW.
CookieOfFortune
A: 

Old NI help note

Just a shot in the dark...could the Qt data be clobbering some of the LV memory space immediately after the exec loop is started?

Underflow
Possibly but that's a long, dark hole that I'm not looking forward to heading down.
dwj
A: 

You probably don't have a QApplication object created when you are trying to call exec() in the QThread. This might be causing your crash. For the main problem, however, I would say that it is very likely you aren't getting any activity in the DLL due to the event loop not executing.

Caleb Huitt - cjhuitt
Can you have QApplication object in a DLL?
dwj
@dwj: I wouldn't try it, but you might get away with it if you knew no other dlls or the main application itself contains a QApplication object. You might be able to have some code that checks for one, and instantiates it if there is no other one in existence.
Caleb Huitt - cjhuitt
A: 

How did you declare the DLL call in LabVIEW? Thread safe? or not?
Could you add an snapshot of your code?

Ton

Ton
In the Call Library Function I set Thread as "Run in UI thread", Calling Convention as "C", no Callbacks, and default Error Checking; the same as my other DLL calls. Note the update in the main question.
dwj
A: 

You should change the library call to 'run in any thread' that way the UI thread can still run the event loop.

Brian