07-13-2021 03:34 AM
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
Three bytes after the string are required for alignment.
I always geht this failure:
The library call looks like this:
This is the BD
Performing the call in another way:
Lib call is now:
This leads to the same failure
Does anyone know how to solve this issue?
Best regards
Solved! Go to Solution.
07-13-2021 03:45 AM
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.
07-13-2021 03:54 AM
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?
07-13-2021 03:56 AM
Dear Rolf,
the size of the structure is given by the axternal DLL provider.
07-13-2021 04:12 AM - edited 07-13-2021 04:23 AM
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.
07-13-2021 04:51 AM
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
07-13-2021 04:55 AM
@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.
07-13-2021 04:55 AM
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.
07-13-2021 04:57 AM
It seams to be like the DLL doesn't work propperly but the manufacturer said that there is no problem.
07-13-2021 06:14 AM
Dear Rolf,
this was my first attempt:
The Result was the same error as mentioned before.