LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

StdCall (WINAPI)

Solved!
Go to solution

Dear

 

I know this topic has been discussed here before but It was a std C call library issue.

 

The output structure looks like this:

typedef struct
{
TPCANHandle channel_handle           word
TPCANDevice device_type                 Byte
BYTE controller_number;                    Byte
DWORD device_features;                   DWORD
char device_name[MAX_LENGTH_HARDWARE_NAME]; 33  Byte
DWORD device_id;                            DWORD
DWORD channel_condition;              DWORD
}TPCANChannelInformation;

 

Structure size in byte is 52

Martin_Kunze_0-1626164368629.png

Three bytes after the string are required for alignment.

I always geht this failure:

Martin_Kunze_1-1626164671783.png

 

The library call looks like this:

Martin_Kunze_2-1626164764128.png

This is the BD

Martin_Kunze_3-1626164833196.png

 

Performing the call in another way:

Martin_Kunze_4-1626165089545.png

Lib call is now:

Martin_Kunze_5-1626165167238.png

This leads to the same failure

 

Does anyone know how to solve this issue?

 

Best regards

0 Kudos
Message 1 of 20
(1,681 Views)

The embedded LabVIEW string in a cluster is NOT a C string, and also not a fixed size C array as what your API expects! A LabVIEW string is a pointer to a pointer of memory. This has nothing to do with stdcall or cdecl at all!

 

To simulate what your C API expects you need to place a LabVIEW cluster with MAX_LENGTH_HARDWARE_NAME U8 integers in there. And if MAX_LENGTH_HARDWARE_NAME is really 33 as in your comment you also need to add 3 extra filler bytes after it (or simply increase this cluster to 36 elements in order to align the following DWORD on a 4 byte boundary, then you won't need to append those extra 3 bytes at the end, because they are not there but after the fixed size string.

Rolf Kalbermatter
My Blog
0 Kudos
Message 2 of 20
(1,677 Views)

Hello Rolf,

 

I have doen it in this way.

The three bytes after the string are in the cluster followed by the DWORDS.

Do you have a workin example for this issue?

0 Kudos
Message 3 of 20
(1,673 Views)

Dear Rolf,

 

the size of the structure is given by the axternal DLL provider.

0 Kudos
Message 4 of 20
(1,672 Views)

I fully understand that the size of the struct is a constraint that you have to match and can't change!

 

That is why you have to change your cluster in LabVIEW to match that struct!

 

A LabVIEW string is NOT (please note the emphasis) a C string and neither a fixed size C array!

 

So you can jump high and low but that will not work.

 

The cluster you show really represents this datatype in C (even when you convert the string to a byte array, in C syntax those two are completely synonymous):

 

typedef struct
{
    TPCANHandle channel_handle // Word
    TPCANDevice device_type    // Byte
    BYTE controller_number;    // Byte
    DWORD device_features;     // DWORD
    LStrHandle deviceName;     // Not a fixed size array of 33 Bytes but simply a pointer
    uint8_t filler1;           // Byte
    uint8_t filler2;           // Byte
    uint8_t filler3;           // Byte
    DWORD device_id;           // DWORD
    DWORD channel_condition;   // DWORD
}TPCANChannelInformation;

 

The solution with the string converted to a byte array would sort of work if you then also added a byte array to cluster node configured to create a cluster of 33 elements. Except that there is definitely something wrong with the other elements in that case. (The 4 parameters in front of the string add up to 8 bytes but you only have 6 U8 elements added there, making the memory for the struct in total 50 bytes rather than 52!)

 

But since you anyhow only want to pass an allocated array of bytes to that function, you can do it much easier. Just use an Initialize Array node for an array of U8 elements and n * 52 as size. n is the number of structure elements you want but I wonder why you create 2 of them only while none of the other parameters to the function indicates 2. A function usually has a separate parameter that tells it how many array elements to expect in the array pointer.

 

Unless the second parameter 43 is some command that implicitely indicates that the function receives an array of two struct elements it may fill in at most (or the function itself is documented to never fill in more than 2 elements), there is something fishy about this.

 

This all assumes of course that your documentation about the size for the TPCANHandle and TPCANDevice is correct. Without seeing the header where they are declared I can't confirm or deny this claim.

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 20
(1,650 Views)

Dear Rolf,

 

thank you for your answer.

Not mentioned here:

I ask the driver how many channels are found.

In my case there are just two.

My forst attempt was:

Initialize an array with N * 52 U8 elements and feed this into the the channel information call.

The parameters above are 0 for noebus and 43 for the requested information.

 

This useless attempt also didin't work for me.

So I tried to use a cluster and adapt to type. That doesn't work too.

Putting a manual made array into the lib call doesn't change anithing also.

 

I don't know how to solve this issue.

 

Regards

 

Martin

0 Kudos
Message 6 of 20
(1,637 Views)

@Martin_Kunze wrote:

 

I don't know how to solve this issue.


Maybe post the header file for that API for a change? I suspect that something you think you interpreted correctly from that header isn't quite that way.

Rolf Kalbermatter
My Blog
0 Kudos
Message 7 of 20
(1,634 Views)

Dear Rolf,

 

AFAIK you always can use a U8 array to let the dll put something in it.

Only the size matters.

Worin size => Crash

 

This method is nery because of the needed data reconstruction bus it has always worked for mee.

Only in this case it doesn't and I don't know why.

0 Kudos
Message 8 of 20
(1,633 Views)

It seams to be like the DLL doesn't work propperly but the manufacturer said that there is no problem.

0 Kudos
Message 9 of 20
(1,630 Views)

Dear Rolf,

 

this was my first attempt:

Martin_Kunze_0-1626174811746.png

 

The Result was the same error as mentioned before.

0 Kudos
Message 10 of 20
(1,608 Views)