LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

PostLVUserEvent and Embarcadero (C Builder)

As to assigning the refnum to the variable before calling Show(): That is simply a safety measure when dealing with event driven programming. If you can't be 100% sure that the Show() function won't possibly trigger the event function that might refer to the variable, you should always try to program in such a way that you have initialized any variables before any event callback that refers to those variables could be triggered. It's likely that the function in question is only really triggered by a true user click event into the form so chances are very small that it will happen before the variable is assigned, but it's those VERY small to indefinitely small chances that makes the most difficult to debug problems!

 

And since there is no single reason that requires the variable assignment to occur after the call to Show(), I would simply save myself the time to investigate if Show() could possibly trigger that event and put the assignment before any other method call.

Rolf Kalbermatter
My Blog
0 Kudos
Message 11 of 30
(914 Views)

I made a few corrections according to your suggestions, and now, it works.

 

So, thanks one more time.

 

New code joined (vi in LV2011).

I did not test the executable version.

 

The only remainding pb is that LV still crashes at the end ( about 15 seconds after i close the vi ???, everything looking allright before it)

 

I think the cause is in the C++ code, maybe i do not free something as it should be. 

Does the "GetModuleHandle(NULL)" function need something to be done at the end ?

0 Kudos
Message 12 of 30
(907 Views)

 

lib = LoadLibrary("P:\Program Files\National Instruments\Shared\LabVIEW Run-Time\2012\lvrt.dll");

 

You shouldn't attempt to load the DLL by full path. In older Windows versions it didn't matter but since Windows XP you have in fact SxS and attempting to load a DLL by full path will load it into memory even if another DLL of the same name but a different location is mapped into the process space. Two LabVIEW kernels in the same process is a sure way to cause very nasty crashes, although it is likely that it will not wait until you close LabVIEW before it crashes.

 

I would clear out Fiche->EvtRef in FermeFiche() and protect the call in the callback to only call the LabVIEW manager function if it is not NULL.

 

GetModuleHandle() should not increment the module refcount according to MSDN so there should be no need to Free it too. There is a potential problem in the case of Loading lvrt.dll as that should be freed when using LoadLibrary() but it should also be possible to use GetModuleHandle("lvrt.dll") and then you do not have that problem.

 

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 13 of 30
(902 Views)

It is OK now, no more crashes.

 

I still have to test an exe version.

 

About

lib = LoadLibrary("P:\Program Files\National Instruments\Shared\LabVIEW Run-Time\2012\lvrt.dll");

I knew there was something wrong with full paths, did not knew what.

But in this case, that part of code was never executed.

 

Good evening

 

 

 

0 Kudos
Message 14 of 30
(897 Views)

@gosaure wrote:

It is OK now, no more crashes.

 

I still have to test an exe version.

 

About

lib = LoadLibrary("P:\Program Files\National Instruments\Shared\LabVIEW Run-Time\2012\lvrt.dll");

I knew there was something wrong with full paths, did not knew what.

But in this case, that part of code was never executed.

 

Good evening

 

 

 


It will be executed when you run it in an executable!

 

And loading DLLs by full path does not have to be evil. But you need to be very careful to not pass any objects from one of them to the other one that are defined in terms of resources managed by each of them. LabVIEW Refnums are such objects since they have only a meaning in the context of where they were created, so passing a refnum received from a lvrt.dll used by the LabVIEW application to a different lvrt.dll loaded by your DLL will at best cause mgArgErrs (error code 1) but can also end in crashes.

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 15 of 30
(892 Views)

Hello Rolf,

 

I have a problem about applying dll in LabVIEW which is seem to have relation with this topic because I feel it likes the unti-process of what you talked about. What I want to know is whether an event will happen when an running VI is stopped by clicking the termination debug button. I want to use this event to transfer some parameters to my dll.I want to know the method of using this event.

In Load Library Node, I notice that there is termination callback function defined in dll which can settle parts of my problem in such an idea. But how let LabVIEW transfer parameters to dll correctly? I try some methods, but always have error happened.

 

Looking forward to your reply!

 

Best regards!

 

0 Kudos
Message 16 of 30
(871 Views)

Well you are probably refering to the Reserve, Unreserve, and Abort "callback" functions that you can configure.

 

Using them is an advanced feature that is definitely not trivial to do, and I haven't come across a need for that yet. It's also involved.

 

Basically each of these functions has the same prototype:

 

MgErr (*funcPtr)(InstanceDataPtr *ptr);

 

To use the Abort function you have to implement all three of them.

 

The Reserve() allocates a memory location to store whatever your library needs to refer to any resources that may have to be aborted at runtime. It may also store this pointer somewhere in a module global location in order to be able to refer to it in the Shared Library cleanup procedure just to be safe.

 

The Unreserve() function deallocates this pointer and any resources it may contain.

 

You can then configure your actual function call to receive as one of its parameters the InstanceDataPtr that your Reserve() function has allocated. This parameter is implicit in that it will not show as a connectable CLN terminal. In your function you start some asynchronous operation and store handles or any other information necessary to refer to this asynchronous operation in the Abort() and/or Unreserve() call.

 

The Abort() function is called by LabVIEW for every CLN instance in an aborted VI hierarchy. It receives the pointer that the Reserve() function has created and needs to refer to whatever information you have stored in there to abort any asynchronous operation previously started.

 

This only is really useful if you have some sort of asynchronous API that you can call internally in your CLN function.


The principle would be something like this:

 

struct {

    HANDLE handle;

} AsyncOperationRec, *AsyncOperationPtr;

 

EXPORT MgErr Reserve(AsyncOperationPtr *ptr)

{

    *ptr = DSNewPClr(sizeof(AsyncOperation));

    if (!*ptr)

    {

        return mFullErr;

    }

    return mgNoErr;

}

 

EXPORT MgErr Unreserve(AsyncOperationPtr *ptr)
{

    if ((*ptr)->handle)

    {

        // Abort and close the operation

        AsyncOperationAbort((*ptr)->handle);
        (*ptr)->handle = NULL;
    }

    DSDisposePtr(*ptr)

    return mgNoErr;

}

 

EXPORT MgErr Abort(AsyncOperationPtr *ptr)
{

    if ((*ptr)->handle)

    {

        // Abort and close the operation

        AsyncOperationAbort((*ptr)->handle);

        (*ptr)->handle = NULL;

    }

    return mgNoErr;

}

 

EXPORT MgErr MyFunction(AsyncOperationPtr *ptr, ......)

{

    if ((*ptr)->handle)

    {

        // What's this? The operation is supposedly already going on!!!

        return error;

    }

    (*ptr)->handle = CreateHandle(...);

    if (!(*ptr)->handle)

        return error;

 

    err = AsyncOperationStart((*ptr)->handle, ...);

    if (!err)

    {

        while (!AsyncOperationReady((*ptr)->handle)

        {

            // Give up the CPU to avoid hogging it

            WaitSomeTime(10);

        }

        err = AsyncOperationClose((*ptr)->handle);

        (*ptr)->handle = NULL;
    }

    return err;

}

 

Rolf Kalbermatter
My Blog
Message 17 of 30
(864 Views)

Thanks for the quick reply!

 

Now I have already settled the dll callback problem by your help. You really explained clearly what I was guessing.

 

I want ask you another question.  Is it has  an event or a callback function can be used when I terminal an running VI by clicking the abort debug button which the ADE provides. If the ADE does, how to use the event or callback

 

function? 

 

Looking forward to your reply!

 

BEST REGAEDS!

0 Kudos
Message 18 of 30
(851 Views)

Sorry I have to admit I'm not understanding what you are asking.

Rolf Kalbermatter
My Blog
0 Kudos
Message 19 of 30
(845 Views)

Ok, rolfk. I try to explain my problem again.

 

For instance, my program has only two Load Library Nodes. The function of the first node is to save the input task name in a register table. The second one is to delete the task name from the register table. The requirement is that task

 

names in the register table must be different. Otherwise error has to be reportted. Now I place a breakpoint between the two nodes.Run the VI with "aaa" as the input task name. When the vi runs at the breakpoint, I click the terminal

 

debug button to stop the vi.捕获.PNG

 

Then when I run the VI again with the same task name,"aaa", the VI reports error. But it's not expected. So I want to kown if there is an event or a function can be used when I click the terimal debug button.

 

Hope this time I make the problem clear.

0 Kudos
Message 20 of 30
(829 Views)