Jump to content

How to call PostLVUserEvent() with a cluster of scalars from C++?


Recommended Posts

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 by Yair
Link to comment

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 by asbo
Link to comment

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.

Link to comment

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).

Link to comment

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 by Yair
Link to comment

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!).

Link to comment

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.

Link to comment
  • 3 years later...

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

post-53317-0-31050900-1426594261.png

Link to comment

 

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.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.