I am working on writing a wrapper dll to interface a communication dll for a yokogawa WT1600 power meter, to a PC based automation package. I got the communication part to work but I need to thread it so that a 50ms scan time of the automation package can be maintained. (The Extended Function Block (EFB) Call will block the scan until it returns)
These are the steps I need to do.
- Call EFB
- EFB creates a thread to perform communication setup (takes about 200ms to do)
- EFB returns EFB_BUSY while the thread is doing the work 3a. (automation program continues scanning until it comes back to the EFB call)
- Call EFB passing in that it returned busy on the last call
- EFB checks if the thread has returned
- If the thread returned Then the EFB returns success, Else return EFB_BUSY
- repeat 3a-6 until efb returns success
So my problem is, how do I create a thread that exists past the life of the function that called it? and how do I get that thread return value when I call back into the dll?
EDIT #1
HeavyFunction::HeavyFunction^ hf; //HeavyFunction is a class that has a time consuming function in it
ThreadStart^ efbThreadDelegate;
Thread^ efbThread;
if( pEfbData->nBlockingRecall != DOEFB_BUSY ) {
hf = gcnew HeavyFunction::HeavyFunction;
hf->iiStart = (int)(pEfbData->uParams[0].dw);
hf->iiEnd = (int)(pEfbData->uParams[1].dw);
efbThreadDelegate = gcnew ThreadStart( hf, &HeavyFunction::HeavyFunction::iGetPrime );
efbThread = gcnew Thread( efbThreadDelegate );
efbThread->Start();
return DOEFB_BUSY;
}else if ( efbThread->IsAlive ) {
return DOEFB_BUSY;
}else {
uRetValue->dw = hf->iReturn;
return 0;
}
Will efbThread still have the same thread handle upon a subsequent call?
EDIT #2
I got it to work by creating a global HANDLE for a Mutex and a thread. Initializing the mutex in the init entry point (done upon dll loading) and creating the thread in the main function when a call is actually made to the dll.
I used the sample code from MSDN: Creating Threads as my model.