LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to pass structure with pointer to dll

Solved!
Go to solution

Hi, I want to pass a structure to the DLL (where data is a pointer to fixed length table, capacity and length are variables):

 

struct parser_data {
   uint8_t *data;
   unsigned capacity;
   unsigned length;
};

 

In Call Library Function Node I did add adaptive input and I did create a cluster:

 

tcie_0-1611264234849.png

 

but without success....

 

 

 

0 Kudos
Message 1 of 3
(1,588 Views)
Solution
Accepted by topic author tcie

When you select Adapt to Type, LabVIEW will pass the native LabVIEW data to the DLL. That will look in C as follows for your cluster:

 

typedef struct
{
      int32_t len;
      uint8_t elm[];
} ArrayRec, *ArrayPtr, **ArrayHdl;

typedef struct
{
      ArrayHdl arr;
      uint32_t capacity;
      uint32_t length;
} MyCluster;

int8_t yourFunction(MyCluster *data, uint8_t secondParam);  

 

As you can see this looks somewhat different than your own C declaration and the according memory layout is totally different. LabVIEW arrays and strings are not C pointers but so called handles.

 

While the Call Library node supports configuring parameters to pass C pointers to LabVIEW data if the parameter is directly passed to the Call Library Node, there is no way to configure that handles inside clusters should be also converted. The reason being that the according configuration dialog for that would get complicated beyond comprehension for >95% of the typical LabVIEW users.

 

Generally speaking such parameters are best implemented in a C wrapper shared library that you write yourself, or if you control the source code of your shared library you create a new function with more LabVIEW friendly parameters, for instance:

 

int8_t yourFunction(uint8_t *data, uint32_t buflen, uint32_t *len, uint8_t secondParam);

 

You can also start playing C compiler yourself and building the necessary data structures on the LabVIEW diagram but that gets very quickly very ugly, will make your code be extra difficult to port between 32-bit and 64-bit and generally requires you to know actually more about C programming than if you wrote the C wrapper library, since you also need to understand things such as alignment and exact size of datatypes that is usually taken care of by the C compiler more or less automatically.

 

Besides you made a data size error. unsigned in C is equal to unsigned int and for all current compilers except maybe some obscure embedded compilers an int is nowadays always 32-bit long. (It used to be 16-bit in DOS and Windows 3.1 but unless you went to maybe one of the first C compilers ever written somewhere in the 60ies of last century, never ever 8-bits).

Rolf Kalbermatter
My Blog
0 Kudos
Message 2 of 3
(1,557 Views)

if somebody is interested:

__declspec(dllexport) bool __cdecl tlv_parser_get_header_(uint8_t *data, uint8_t *capacity, uint8_t *length, tlv_header_t *header){
	struct tlv_parser_data temp_tlv;
	bool status;

	temp_tlv.data = data;
	temp_tlv.capacity = *capacity;
	temp_tlv.length = *length;
	
	status = tlv_parser_get_header(&temp_tlv, header);

	*capacity = temp_tlv.capacity;
	*length = temp_tlv.length;

	return status;
}

 

0 Kudos
Message 3 of 3
(1,525 Views)