LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Complex cluster(array with static size) in calling dll.

Hi there:

 

I am trying to use the DBC API, Function called like below:

 

 

EXTERN_C bool __stdcall DBC_GetFirstMessage( DBCHandle hDBC, DBCMessage* pMsg ); 

 

When I call the DLL, there is a structure:

struct DBCSignal
{
uint32 nStartBit; 
uint32 nLen;
double nFactor; 
double nOffset;
double nMin; 
double nMax;
double nValue;
uint64 nRawValue;
bool is_signed; 
char unit[11];
char strName[66];
char strComment[201]; 
};

There is another  Message structure to the above Signal:

 

struct DBCMessage
{
uint32 nSignalCount; 
uint32 nID;
uint8 nExtend; 
uint32 nSize; 
DBCSignal vSignals[512]; 
char strName[66];
char strComment[201]; 
}

 

  The point is  DBCSignal vSignals[512];

 

I've tried to solve it like attachment,but the program will crash.

 

How to create struct “DBCMessage” ,any good suggestions?  Thanks a lot.

qq.png

 

个人博客www.miitch.cn
0 Kudos
Message 1 of 7
(1,932 Views)

What is "the DBC API"? Googling that function call doesn't give any results (besides your post). Is it the XML\DBC API? 

 


@chchua78 wrote:

 

  The point is  DBCSignal vSignals[512];

  


How do you know? Does it work when it's an empty array?

 

Did you have any success with this DLL (other functions)?

 

+ Are you sure the calling convention is correct?

+ Are you sure those inputs are char[] and not char*?

+ Not sure if those char[] should have a size I32 before them.

+ You convert the array of signals to a cluster. An array is expected, and an array begins with it's size. A cluster doesn't. I'd stick with the array of signals.

+ You don't set nSignalCount to the size of the signal array.

+ You don't set nSize to the size of <what is should be>. Could be size in bytes of nSignalCount of the size of the entire structure?

+ A Boolean is probably an U8 (not an U32).

 

As long as more then 2 or 3 of those items are uncertain, you have to find a way to rule them out one by one...

0 Kudos
Message 2 of 7
(1,877 Views)

There are many people around these boards who understand C-family compiler nuances much better than I.   I can suggest some possible issues, but am ill-equipped to know the specific solution.

 

There can be an issue where C-like compilers may choose to align struct fields on 16-, 32-, or maybe nowadays 64-bit boundaries.  So when a DBCSignal has a 'char strComment[201]' field, it's possible that the compiler will set aside 202 or 204 bytes for that field to maintain alignment in memory.  Same idea holds for other fields potentially.

 

It can be difficult to know on the face of things *exactly* how many bytes a C-family compiler will use for such a struct.  It can depend heavily on compilation options.

 

The really tedious thing I've done in the past is to make a LabVIEW u8 array that's bigger than the largest possible struct size and feed *that* (as pointer or handle) into the dll.  Then I'd do some tedious trial and error where I attempt to populate the u8 array that could represent each field according to different possible candidate alignment settings, observe the results, and start figuring out the actual memory layout of the DBCSignals struct within the compiled dll.

 

You've *gotta* get the DBCSignals nailed down before you even consider tackling the DBCMessage which contains a large array of DBCSignals.

 

My very speculative guess is that the first field of DBCSignals where you need to start guessing much about size is 'bool is_signed'.  I'd further advise that you make sure your char[] arrays are populated with NULL terminators (hex 0x-00) in their last element, maybe also in any extra bytes of padding you allow for alignment. 

 

And that's pretty much all I can tell you.  If a more knowledgeable poster shows up, believe them over me.  Good luck!

 

 

-Kevin P

Message 3 of 7
(1,864 Views)

Cross-posted here: https://lavag.org/topic/20403-how-to-deal-with-clusters-containing-clusters/

 

As mentioned by another poster there, padding is an issue. However, perhaps the biggest problem you have now is that Array to Cluster doesn't know how many elements should be in the cluster - it cannot know the size of the array. It defaults to 9 elements (that's arbitrary), and has a maximum size of 256 elements. You could create two clusters of 256 elements and bundle them together to get a cluster containing 512 elements.

0 Kudos
Message 4 of 7
(1,857 Views)

Hi there, I have not tried this but you may find this example code from "Jolt" useful here:

 

Universal Cluster to C Struct with Endian-ness and Padding

0 Kudos
Message 5 of 7
(1,821 Views)

Hi, wiebe@CARYA.Thank you for your reply.
Actually ,I'm writing a VI to anayse the DBC file (CANbus),like Vector and NI. But what we use is our own hardware.
I've realized it's a data structure alignment and padding problem. It ' s hard for me(neophyte) , but I ' ll try.image001(01-17-10-52-10).png

 

 

 

个人博客www.miitch.cn
0 Kudos
Message 6 of 7
(1,804 Views)

@Gregory wrote:

Hi there, I have not tried this but you may find this example code from "Jolt" useful here:

 

Universal Cluster to C Struct with Endian-ness and Padding


That looks interesting. Not sure if an how it would work. If the dll expects a pointer to cluster, but gets a pointer to an array, wouldn't the first 4 bytes of the array be the size of the array? That will not be what the dll expects. Anyway, should be easy to try it out.

0 Kudos
Message 7 of 7
(1,792 Views)