LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

c++ header implementation

Hello,

I've had this question before, but now I'm trying it from a new approach. THe first time I tried to implement this headerfile in LABVIEW 6.1 I tried a direct approach, but that didn't work out well.

My project is to implement the GetParmType stucture from this headerfile into a LABVIEW application.
The approach I'm trying at this moment is to build an array of 326 bytes, and fill this array with the data from my EEPROM.

The first 64Bytes is :         char            Version[VERSION_LEN];
the next 2 bytes are the:    unsigned short  DeviceId;

(this is the DeviceInfoType structure)

the next byte is:                unsigned char   NrChannels;
then 2 bytes for:               unsigned short  NrPixels;
and 1 byte for:                  unsigned char   Sensor;
(this is the DeviceConfigType;)

the rest of the array should be filled with the ChannelParmType structure. The maximum devices that can be connected is 8 pieces, so this should be a loop that runs the 8 times.

Can somebody help me with this? I have no idea how this is done or how to fill an array this way.

The headerfile is attached.

Many thanx

Koert
0 Kudos
Message 1 of 6
(3,090 Views)
Well, you seem to not have taken the advice from Lucyan and go with the wrapper DLL. I can really tell you that it is almost always the best to go with that, albeit that requires some C programming knowledge. But trying to go without wrapper DLL actually requires at least as much C programming knowledge you know!

As long as it is only for a single function, you can somtimes try to do it all in LabVIEW but it is a really laboursome work. Enclosed see a solution which should more or less do what you need for this particular function. There is no way to get it easier without using a wrapper DLL and for some functions you just have to accept that trying to go without wrapper is a sure way into insanity.

Rolf Kalbermatter
Rolf Kalbermatter
My Blog
Message 2 of 6
(3,073 Views)
Thanx for the advice, and I will try to build a wrapperlibrary or sent this project to a 3th party. My  manager wouldn't believe it couldn't  be solved without a wrapper library.

Thanx for  the advice.


0 Kudos
Message 3 of 6
(3,068 Views)
The DeviceConfigType is a great example of what I mentioned before about the dangers of mapping C structures to LV...
 
typedef struct
{
    unsigned char   NrChannels;         // number of channels
    unsigned short  NrPixels;           // number of pixels
    unsigned char   Sensor;             // Sensortype
} DeviceConfigType;
Typically in C/C++, you are going to have the compiler set to a 4-byte alignment (this is the default for 32-bit Windows). What this means is that this structure is going to take up 12 bytes. One DWORD (4-bytes) for each entry. Why? That is what 4-byte alignment means...each element of a structure starts on an address that is a multiple of 4. The reason you want to do this is that it makes accessing the data faster, even though it ends up taking more memory (see memory and cache architectures for the reason).
 
In LabVIEW CIN's, you'll notice that we require a 1-byte alignment (historical reasons that we can't change without breaking every CIN that exists out there). That means that the same structure would only take up 4 bytes (as I assume the designer of the structure intended).
 
Thus when you think you are accessing DeviceConfigType.NrPixels, you have already gone beyond the memory allocated by LabVIEW.
 
 
0 Kudos
Message 4 of 6
(3,057 Views)


@Lycangeek wrote:
The DeviceConfigType is a great example of what I mentioned before about the dangers of mapping C structures to LV...
 
typedef struct
{
    unsigned char   NrChannels;         // number of channels
    unsigned short  NrPixels;           // number of pixels
    unsigned char   Sensor;             // Sensortype
} DeviceConfigType;
Typically in C/C++, you are going to have the compiler set to a 4-byte alignment (this is the default for 32-bit Windows).


I think Visual C (at least in version 6) uses a default alignement of 8 byte. However variables are usually aligned to the lesser of the default alignement or the variable size. So I would hazard that this particular structure actually would take up 5 byte since Visual C will add a fill byte between
NrChannels and NrPixels.

However you are right that in my example I didn't account for padding at all. Another problem is that there will be three additional fill bytes after Sensor, to make the first float in the ChannelArray align on a four byte boundary.

So this would probably mean that for the DeviceConfig we should copy out at least 7 bytes and add a fill byte between channels and pixels and the offset for the channel array should be 74 instead of 70. Also the array intialization should then be 330 instead of 326.

There still are some uncertainities. Unless the #pragma pack(x) statement is in the header file (in this case not) you still can't be certain that the DLL was compiled with the default alignment, although it is quite likely.

Rolf Kalbermatter
Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 6
(3,038 Views)
I'm working on the wrapper library in my working hours, but yesterday evening I build the VI, as described above. It works perfect, even with more channels, there is only one problem. If I run it a second time it doesn't work anymore. The communication with my device is still intact, cause the AVS_INIT function returns a "0" and the AVS_DONE returns also a "0" (wich means  it woks good) only the AVS_GetParameter function returns a "-1000". The way to solve this is to close LABVIEW and restart it again, and now I'm going to solve this problem.

Thank you all for the input.

Koert


Smiley Wink
0 Kudos
Message 6 of 6
(3,028 Views)