LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Using a DLL generated by LV in multithreaded Visual C++ program

Unfortunately the issues surrounding when you need the pumping and when you don't is too complex to describe or even fully understand - I don't think any developer here could give you an absolute list (not counting the fact that the list would change from version to version).
 
Now, I'm not saying that this is specifically the problem you are having but it has the symptoms of what I've seen before, and if the main thread isn't doing any message pumps, or calling any OS routine that pumps messages, then you are set up for a deadlock to happen.
 
So, I would recommend creating a thread in your main() routine which calls the LVDLLStatus routine and then sits and pumps messages. Either way you want that in your MT code.
Message 11 of 22
(2,251 Views)

Looks like you are right!!! I did something and tried to run the program with a simple DLL again. Somehow it didn't run this time.

Anyway, I am trying to make your PumpMessages() work in my test program. I attached the files to explain what I am trying to do here. Without the part for pumping messages, the program works. But, as you can see in my test program, including the pump messages loop directly in main() didn't work and I commented the part out. I guess I need your help.

Could you elaborate on spinning up a thread and including this into a VC++ program? Thanks.

Tom

0 Kudos
Message 12 of 22
(2,087 Views)
I forgot to attach the files.
Tom
0 Kudos
Message 13 of 22
(2,083 Views)
Okay, I think the confusion is that the first call to LV and the pump messages must be done from the same thread, and you probably don't want that to be the main thread. What I would do is use your sThread class and create an instance in the main - first thing it does. The execute method for the thread will first call
 
void ExecProc()
{
      LVDLLStatus(NULL, 0, NULL);
 
      /* Do something here - see below */

      PumpMessages();
}
Then, and this is key, once that thread has started executing, you can go ahead with your other code. Therefore the comment block in the code above is where you need do set an event or variable or something to let the main thread know that it can continue. In my ASP.NET example, I don't do any sync but I should. The timing is such that I doubt it would ever be a problem, but it is possible.
 
If you don't do this, it is possible for the main thread to call DllTest60() before LVDLLStatus is invoked.
Message 14 of 22
(2,070 Views)

Brian,

I guess I'm getting desperate here. I'd appreciate it if you can answer the following questions.

1) I included a revised version of the files modified according to your advice. Is this what you meant in my test program? Unfortunately, I get some linking errors. I couldn't find out why.

2) I found that I can run my LV DLL when I put the LV function in my main(),thread-1, and move the other part to the second thread, thread-2. The problem is that I need to have more(for example, thread-3 and thread-4) than one thread run the LV function. Would I still need to pump messages for the thread-3 and -4 even when I have my LV function in main() already?

Thanks,

Tom

0 Kudos
Message 15 of 22
(2,057 Views)
At least I could fix the linking errors in my test program. I attached the revised files. Now, the program is ready for pumpMessages to work. The function from LV DLL doesn't seem to run..... Why???
0 Kudos
Message 16 of 22
(2,052 Views)
I won't be able to do much more than look over the code as I am at NIWeek right now. But to answer a couple of things...
 
1. You don't need to worry about the additional threads - you only need one that calls LVDLLStatus and PumpMessage. In fact, I would recommend making that its own thread and pulling DllTest61 into its own. It is really more of a style issue with the current code, but I think it is best to have the Status/Pump thread seperate so that you can just fire it off and forget about it.
 
2. You are redefining DllTest61 and PumpMessage at the top of the thrTest1.cpp - don't do that since you are already including the header files with them defined. You are going to avoid a lot of heart ache regarding callstacks if you do that.
 
3. Note that PumpMessage() does not return until the WM_QUIT message is sent, so you aren't going to see the "out of CS" until (if even then) the program exits. So I'm not sure right now what you mean by the program doesn't work since I can't run it...but that is something to remember.
Message 17 of 22
(2,048 Views)

Brian,

Seems like I am getting closer. I have set up a separate thread that has LVDLLStatus and PumpMessages. I also put my function in LV DLL into main() and am trying to make the LV DLL function work.

Good news is one of my test LV DLL function worked in MTenvironment, in main() and in other threads generated later. But I found that the LV DLL function works even without the thread for LVDLLStatus and PumpMessages. Here is a funny thing...When I replaced the test LV DLL function with the actual LV DLL function I want to use, only the one in main() worked and the program stopped(got stuck) at the same function in the next thread.

I think this is what you mentioned before. I see one LV DLL function working in an MT program and another function not working in the exactly same MT program!!!

So, here are my questions. (1) Was I right in including the LV DLL function in main()? The thread for pumping messages is called after the LV DLL function. (2) If I was right, I think I did everything set up right for using LV DLL in MT environment. Is it still possible that some LV DLLs do not work?

Tom

0 Kudos
Message 18 of 22
(2,034 Views)
"The thread for pumping messages is called after the LV DLL function"
 
No - you must get the initialization to start first. I recommend the following.
 
1. main() starts. Launches thread (t1) that calls LVDLLStatus, sets notification for main() and then calls PumpMessages().
2. main() waits for (t1) to set notification (how ever you want to do this).
3. main() launches other threads (t2, t3, t4...) and they call LV DLL functions.
 
You can, of course, also have main call LV DLL functions AFTER step #2.
 
Anything else is likely to get you in trouble.
Message 19 of 22
(2,032 Views)
I made a mistake by saying "The thread for pumping messages is called after the LV DLL function". Actually it was called BEFORE the LV DLL function.
 
Anyway, I think I followed your instructions right this time. But somehow it does not work. In my program attached, I tried to use a test LV DLL functions(DllTest61) because the actual functions(DioInit_ygl,DioIter_ygl) requires a DAQ board to run. With the thread for pumping messages, the program locks up. When I commented the LVDLLStatus and PumpMessages in the thread, the program runs. So, something with pumping messages doesn't seem to be right. I need to have this message pumping work to make my actual LV DLL functions work.
 
Tom
0 Kudos
Message 20 of 22
(2,028 Views)