Jump to content

Help setting up dll function


Recommended Posts

I'm having problems getting a particular function ina dll to work. I'll try and provide all the needed documents and files hoping some one can point me in the right direction.

Included in the attachment is the .dll, the VI I'm working on for this function, the documentation for the function, the header file for the dll and a sample C source file that uses this function.

The problem I'm having is the function appears to return the data, but when it attempts to write the data to the indicator, LabVIEW crashes. The function is suppose to be run twice. On the first run you're suppose to have the "ProvidedBufferSze" parameter set to 0 and the "Buffer" = Null. After the run, "NeededBufferSize" will contain the needed bffer size that can be used on "ProvidedBufferSze" on the next call.

The size of the structure containing the data is suppose to be 100 bytes according to the documentation. On the first run of the function, "ProvidedBufferSze" returns 194 with a two channel device in the PC. It seems to me this should be 200. On the second run with either 194 or 200 on "ProvidedBufferSze", the function (running with execution highlighting on), I can see the "Buffer" return a 2 element array. When this array is written to the indicator (or a probe), LabVIEW crashes and I get the Windows "Send Error Report" dialog.

Mainly I just want to verify that I have the CLN setup correctly and my logic in the VI seems correct. After this, I'll probably end up calling the manufacturer to see what they have to say.

Thanks

Ed

Link to comment

Hi:

LabVIEW 7.1 and below requires that you set your VI to be 'reentrant' if you are using that VI as a wrapper for calling a dll. I am not sure if LabVIEW 8.* does not require this. Unfortunately in LabVIEW 7 and below, you could not debug your VI if you set it to be re-entrant

If you do not set LabVIEW 7.1 C dll warpper VI to be re-entrant, then LabVIEW would always burn and crash when writting to front panel controls or when you flip between the block diagram and the front panel. ... I learnt this the hard way but it is in fact documented somewhere in the knowledge base or in LabVIEW help files.

. . . In your case, your wrapper dll call VI does not seem to be reentrant.

Anthony L.

Link to comment

QUOTE(alukindo @ Apr 9 2007, 06:25 PM)

LabVIEW 7.1 and below requires that you set your VI to be 'reentrant' if you are using that VI as a wrapper for calling a dll. I am not sure if LabVIEW 8.* does not require this. Unfortunately in LabVIEW 7 and below, you could not debug your VI if you set it to be re-entrant

I've used many dlls in LabView 7 and have never had to set a VI that had a DLL to reentrant. If you can find the knowledge base article(s) with this information please post them.

In my experience, it is usually a problem with the setup of the DLL being called, or in the DLL itself. If you can get the function to work in a simple C program the way you want to call it from your DLL you are probably in business. Although I have found that DLLs that allocate thier own memory (as yours seems to do) usually require a seperate wrapper DLL that you have to write to make them function reliably in LabView.

YMMV

BTW, I did try and open your code, but since it was saved in 8.2.1 I couldn't open the actual VI. Since 8.2.1 was released less than a week ago, you might consider backsaving to something that is a little more universal, so those who haven't even gotten thier 8.2.1 CDs can actually view the code in LabView. Just a suggestion...

Link to comment

Hi:

Well it looks like the rule for setting a VI to be reentrant when calling dlls may not be a strict one. My re-collection is that my LabVIEW crash problems were resolved when this was done. There are cases where some ActiveX dlls can not even be instantiated unless you set the LabVIEW wrapper VI to use the User Interface (UI) thread --rather than being reentrant

So I think that experimenting with the execution settings is one thing that is worthwhile trying when troubleshooting problems of VIs that call dlls. This may look like approaching things by hit and miss . . . but could lead to some resolution.

Anthony L.

Link to comment

QUOTE(chrisdavis @ Apr 9 2007, 08:10 PM)

I've used many dlls in LabView 7 and have never had to set a VI that had a DLL to reentrant. If you can find the knowledge base article(s) with this information please post them.

In my experience, it is usually a problem with the setup of the DLL being called, or in the DLL itself. If you can get the function to work in a simple C program the way you want to call it from your DLL you are probably in business. Although I have found that DLLs that allocate thier own memory (as yours seems to do) usually require a seperate wrapper DLL that you have to write to make them function reliably in LabView.

YMMV

BTW, I did try and open your code, but since it was saved in 8.2.1 I couldn't open the actual VI. Since 8.2.1 was released less than a week ago, you might consider backsaving to something that is a little more universal, so those who haven't even gotten thier 8.2.1 CDs can actually view the code in LabView. Just a suggestion...

Here's the VI saved back to 8.0. Please note that this version is slightly different than the 8.2 version as the "Data Formats" for the "Adapt to Type" are different between 8.0 and 8.2.

8.2.1 VI will be able to be opened in 8.2 without backsaving. This has always been true for maintenance releases. (at least back to 6.0.2)

I've never had to set a VI as Reentrant either to get a dll call to work. I've got most of the other functions in this dll working and none of their VIs are set to be Reentrant.

Ed

Link to comment

QUOTE(alukindo @ Apr 9 2007, 09:34 PM)

I think you confuse some things here. A VI never needs to be set to reentrant in order to be able to call a CORRECTLY setup Call Library Node. If you need to do that you have a problem with the configuration of your Call Library Node not matching what the actual function needs.

Calling ActiveX components in non single-threaded mode is an entirely different issue. An ActiveX component when installed is registered with the so called threading model it can work with. That is one of the reasons you should install an ActiveX component rather than trying to copy it to another system.

Problems arise when this threading model does not match with what the ActiveX component actually is able to handle. If it says it is multithreading save LabVIEW will just assume that this is the case and not take any precautions to protect the ActiveX component in any way. This means the ActiveX component can be called from different threads in LabVIEW and if the component is not carefully written to handle this properly it will quite soon crash. Putting the VIs into UI thread will basically force LabVIEW to call the ActiveX component always from this single thread and solve the issue, but the problem is really in the registration of the component being bad.

This might be not so apparent in other programming environments since it is quite a bit of work to actually make an application multithreading in them at all so it seldom happens and even if they use multiple threads the programmer tends to access a specific component usually always from the same thread. LabVIEW however simply has multiple threads and also uses them unless it is explicitedly informed not to do that for certain things.

Rolf Kalbermatter

QUOTE(Ed Dickens @ Apr 9 2007, 03:02 PM)

I'm having problems getting a particular function ina dll to work. I'll try and provide all the needed documents and files hoping some one can point me in the right direction.

Included in the attachment is the .dll, the VI I'm working on for this function, the documentation for the function, the header file for the dll and a sample C source file that uses this function.

The problem I'm having is the function appears to return the data, but when it attempts to write the data to the indicator, LabVIEW crashes. The function is suppose to be run twice. On the first run you're suppose to have the "ProvidedBufferSze" parameter set to 0 and the "Buffer" = Null. After the run, "NeededBufferSize" will contain the needed bffer size that can be used on "ProvidedBufferSze" on the next call.

The size of the structure containing the data is suppose to be 100 bytes according to the documentation. On the first run of the function, "ProvidedBufferSze" returns 194 with a two channel device in the PC. It seems to me this should be 200. On the second run with either 194 or 200 on "ProvidedBufferSze", the function (running with execution highlighting on), I can see the "Buffer" return a 2 element array. When this array is written to the indicator (or a probe), LabVIEW crashes and I get the Windows "Send Error Report" dialog.

Mainly I just want to verify that I have the CLN setup correctly and my logic in the VI seems correct. After this, I'll probably end up calling the manufacturer to see what they have to say.

Thanks

Ed

Well, you can't embed a string in a cluster and just pass that to the DLL. A LabVIEW string is something very different than what a C DLL would expect. Also the prototype clearly shows the string as a fixed size entity which means it is inlined in the structure and not even a C string pointer (which actually makes it easier for us to call it from LabVIEW if done right). So what you want to do is passing a flat buffer of bytes to the function with the needed size.

Something like what is shown in the attachment.

One afterthought. Your size numbers you mention indicate that the structure only uses 97 bytes for the structure. From what I can see in the header file the only thing I'm not sure about is the BOOLEAN datatype. The usual Windows type is BOOL which is a 32bit integer but BOOLEAN seems to be defined as a BYTE type. So obviously your structure would be only 97 bytes long and Softing seems not to use padding in their API which makes the buffer always a multiple of this value.

This would mean you will have to adjust the attached VI slightly to get the right data from the buffer. Basically changing the 20 constant to 17 should already work although you may have to make sure that the embeed boolean gets interpreted right too.

Rolf Kalbermatter

Link to comment

QUOTE(rolfk @ Apr 12 2007, 05:01 AM)

Well, you can't embed a string in a cluster and just pass that to the DLL. A LabVIEW string is something very different than what a C DLL would expect. Also the prototype clearly shows the string as a fixed size entity which means it is inlined in the structure and not even a C string pointer (which actually makes it easier for us to call it from LabVIEW if done right). So what you want to do is passing a flat buffer of bytes to the function with the needed size.

Something like what is shown in the attachment.

One afterthought. Your size numbers you mention indicate that the structure only uses 97 bytes for the structure. From what I can see in the header file the only thing I'm not sure about is the BOOLEAN datatype. The usual Windows type is BOOL which is a 32bit integer but BOOLEAN seems to be defined as a BYTE type. So obviously your structure would be only 97 bytes long and Softing seems not to use padding in their API which makes the buffer always a multiple of this value.

This would mean you will have to adjust the attached VI slightly to get the right data from the buffer. Basically changing the 20 constant to 17 should already work although you may have to make sure that the embeed boolean gets interpreted right too.

Rolf Kalbermatter

Thanks Rolf, that did the trick. My lack of C knowledge is showing. :blink:

I did manage to figure out that the 20 needed to be 17. I noticed the returned size was off as well and thought that was causing the original problem. I cna't figure out what they are doing with the boolean either, but it doesn't seem right.

Ed

Link to comment

QUOTE(Ed Dickens @ Apr 12 2007, 11:18 AM)

Thanks Rolf, that did the trick. My lack of C knowledge is showing. :blink:

I did manage to figure out that the 20 needed to be 17. I noticed the returned size was off as well and thought that was causing the original problem. I cna't figure out what they are doing with the boolean either, but it doesn't seem right.

Ed

Well I checked and BOOLEAN is an alternative Windows SDK definition and equals BYTE which is basically an 8bit value. Some Windows APIs use that for boolean parameters and return values, although not the standard Win32 API, which normally uses BOOL (a 32bit integer boolean).

Rolf Kalbermatter

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.