Yair Posted November 22, 2011 Report Share Posted November 22, 2011 (edited) I'm working with a C++ programmer and trying to get some data into LV. We've looked at the examples for PostLVUserEvent() both on NI's site (here) and on LAVA and managed to get events in LV. The problem is that the event data is a struct with a DWord and a few floats or doubles and for some reason when we try to create an equivalent LV cluster (a U32 and SGLs or DBLs) the first integer gets through fine, but the floating points values are completely meaningless. We also did a quick test with a cluster with just three INTs and we still only get the value for the first one - the other two are always zero. I don't have the code at the moment (and it's too messy anyway at the moment), but does anyone know what would be the correct C/C++ code to get the event reference from LV (although that part seems to work fine) and to send an event of a struct with a few scalars (preferably with doubles as well)? Edited November 22, 2011 by Yair Quote Link to comment
asbo Posted November 22, 2011 Report Share Posted November 22, 2011 (edited) My first stray thought is to make sure that the C++ code isn't padding the struct - I believe the default is 8 bytes, so your 4-byte int has 4 empty bytes appended (presumably for DWORD alignment). Use the #pragma pack(1) directive to enforce this. If you put the directive right before the struct definition in the appropriate header file, every function which relies on the struct will pack it properly. If, for some reason, other parts of the C++ require different packing, you can call pack() again right after your structure definition. MSDN documentation on pack(): http://msdn.microsof...1(v=vs.80).aspx It looks like you can alternatively use align() in the declaration of your data type for the same effect. I have only ever used pack() before, so I can't vouch for this approach. If you can't change the C++ code right away, you can just pad your cluster in LV from {int, dbl, dbl} to {int, int, dbl, dbl, dbl, dbl}. The duplicate of each data type should be garbage or empty. Edit: Thinking through this, your second double should have some value - but maybe your default packing isn't 8. Edited November 22, 2011 by asbo Quote Link to comment
Yair Posted November 22, 2011 Author Report Share Posted November 22, 2011 Good point. I know that LV aligns to 1 byte on Windows, but I don't know what the C++ code does, so I'll be sure to look at it tomorrow. Hopefully that's the the issue. Quote Link to comment
asbo Posted November 22, 2011 Report Share Posted November 22, 2011 Bump for my edit, in case you miss it. Quote Link to comment
Rolf Kalbermatter Posted November 23, 2011 Report Share Posted November 23, 2011 Good point. I know that LV aligns to 1 byte on Windows, but I don't know what the C++ code does, so I'll be sure to look at it tomorrow. Hopefully that's the the issue. If it is Visual C+ it for sure uses 8 byte default alignment. So wrap the declaration of the struct between #pragma pack(1) typedef struct { .......... } Structname; #pragma pack() [/CODE]It's always a good idea to reset any alignment setting back, as otherwise you get a big mess with the order of includes changing the behavior. Quote Link to comment
Aristos Queue Posted November 24, 2011 Report Share Posted November 24, 2011 I looked at the linked file... there's no mechanism that I see in that demo to change the type of the event. What header do you edit to change the data type? Quote Link to comment
Yair Posted November 24, 2011 Author Report Share Posted November 24, 2011 It is indeed VC++, so the alignment may well be the issue. I relayed the info to the C++ guy and hopefully by tomorrow I should have an answer. AQ, I think he simply copied the example code and then added the struct, since the second parameter for the function is supposed to be LV data. In the case of the test code with the ints, it looks like this: typedef struct _EventSend { _EventSend() { dwMask = 0; iA = 0; iB = 0; } DWORD dwMask; int iA; int iB; } EVENT_SEND; EVENT_SEND eventF; // snip... //The code is actually supposed to work with several devices, so we keep several event references in an array PostLVUserEvent(*(lvUserEventRef[iDevice]),(void *)&eventF); } [/CODE]Once we get it working, I'll get him to create example code which (if you want) I can then send you so that you incorporate it into the original document (or I can add a comment there with a link). Quote Link to comment
Yair Posted November 24, 2011 Author Report Share Posted November 24, 2011 (edited) OK, I'm not sure why, but he says that now it seems to be working regardless of which packing he sets. Here's an example which includes an 8.6 VI, the C++ source and a DLL compiled in Visual Studio 2008. This seems to work fine, but, as I understand it, isn't essentially different from what we did earlier in the week, so I'm not sure why it didn't work then. When you run the example, you should get a running counter in the int and 1.1 in the other two. Thanks. DLL LV Event.zip Edited November 24, 2011 by Yair Quote Link to comment
Rolf Kalbermatter Posted November 25, 2011 Report Share Posted November 25, 2011 OK, I'm not sure why, but he says that now it seems to be working regardless of which packing he sets. Here's an example which includes an 8.6 VI, the C++ source and a DLL compiled in Visual Studio 2008. This seems to work fine, but, as I understand it, isn't essentially different from what we did earlier in the week, so I'm not sure why it didn't work then. When you run the example, you should get a running counter in the int and 1.1 in the other two. Thanks. Well there is a #pragma pack(1) so it sure will work. And more importantly, this structure has no alignment issue since a float is a 4 byte entity, so together with the int it aligns the double on an 8 byte boundary, no matter what packing definition is used. Change the float to a double (and make the according change in the VI too!!!!) and the #pragma gets important again (or he also changed the default alignment in the project settings!). Quote Link to comment
Yair Posted November 26, 2011 Author Report Share Posted November 26, 2011 I get the feeling that when we tested earlier in the week, there was some mix up when we working back and forth, because one of the older DLLs which was supposed to have an int and didn't work, was actually returning float data, so when I replaced the I32 with a SGL, that code started to work fine. Quote Link to comment
Roopesh Posted March 17, 2015 Report Share Posted March 17, 2015 Hi All, I getting an exception when calling a c++ dll which has PostLVUserEvent to trigger the LabVIEW event structure. This dll has typedef stuct as described below (nested structure type), the same data structure is sent using PostLVUserEvent to the LabVIEW event. --------------------------------------- typedef struct abc{utf8_t *name;uint32_t numChildren;struct abc *children;}abc; --------------------------------------- Please help me to create a nested structure cluster in LabVIEW. I am creating a cluster as shown in image attached: Thank in advance Quote Link to comment
Rolf Kalbermatter Posted March 17, 2015 Report Share Posted March 17, 2015 Hi All, I getting an exception when calling a c++ dll which has PostLVUserEvent to trigger the LabVIEW event structure. This dll has typedef stuct as described below (nested structure type), the same data structure is sent using PostLVUserEvent to the LabVIEW event. --------------------------------------- typedef struct abc { utf8_t *name; uint32_t numChildren; struct abc *children; } abc; --------------------------------------- Please help me to create a nested structure cluster in LabVIEW. I am creating a cluster as shown in image attached: Thank in advance Duplicate post here. Refer to the answer there. BTW: the original topic is only related in respect to the PostLVUserEvent() function but explicitly was about a quite different and more practical data structure. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.