LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

how to pass a cluster into c DLL's CLN parameter

Solved!
Go to solution

I have a C DLL function as follow

int _CALL_CONVENTION _judge_spi_read(
int handle,
char *channel_list,
char *start_addr,
char *stop_addr,
int *CaptureData,
JUDGE_SPI_PATTERN_DATA *pattern_info   //pass by pointer
);

 

JUDGE_SPI_PATTERN_DATA is a struct define as follow

struct JUDGE_SPI_PATTERN_DATA {
int Data_Group_Count=0; 
int SignBitFirst=0; 
int CondenseMode=0; 
int CaptureCounts = 0; 
char *Start_Address1 = NULL;
char *Start_Address2 = NULL;
char *Start_Address3 = NULL;
char *Start_Address4 = NULL;
char *Start_Address5 = NULL;
char *DataString1 = NULL;
char *DataString2 = NULL;
char *DataString3 = NULL;
char *DataString4 = NULL;
char *DataString5 = NULL;
};
typedef struct JUDGE_SPI_PATTERN_DATA JUDGE_SPI_PATTERN_DATA;

 

and in shared library parameter setting is  in the attached file (parameter_setting.png)

in vi, I already create a cluster and connect to the parameter, but when run into this CLN, the program will crash.

I think the cluster not correct pass into C DLL function, which step is wrong ?

0 Kudos
Message 1 of 6
(2,352 Views)

All your char * string pointers need to be replaced by 32-bit integers in LabVIEW 32-bit and by 64-bit integers in LabVIEW 64-bit. Then it won’t crash. Now comes the really interesting question: What is the management contract the programmer selected for these buffers? Are they allocated by the DLl and passed back? If so are they managed by the DLL such as being a static buffer in the DLL being overwritten at each call (which would totally be not multithreading safe!)? Or does the caller need to deallocate them and if so with what function?

Are they supposed to be initialized by the caller? If so with what size?

All of these questions have to be answered with yes or no before you can even think about trying to use this API no matter if you call it from C or LabVIEW. And this information can be ideally gotten from the Programmers Manual for your library but the world is seldom ideal.😀

Many programmers forget that that is very essential information as it is crysttal clear in their mind how their API is supposed to work (at least until they need to revisit the software a year later and start cursing about the ignorant programmer who could think up such a stupid management contract. Ohh that was me? Impossible!)

Rolf Kalbermatter
My Blog
Message 2 of 6
(2,334 Views)

I have already change structure as follow

struct JUDGE_SPI_PATTERN_DATA_FIXED {
int Data_Group_Count ;
int SignBitFirst;
int CondenseMode ;
int CaptureCounts ;


char Start_Address1[64];
char Start_Address2[64];
char Start_Address3[64];
char Start_Address4[64];
char Start_Address5[64];

char DataString1[128];
char DataString2[128];
char DataString3[128];
char DataString4[128];
char DataString5[128];
char DataMask2[128];
char DataMask3[128];
char DataMask4[128];
char DataMask5[128];
};

 

and use string to Byte Array in Labview to change char[] to integer , But, the sting still can not correct pass into C++ function... (cluster.png)

What did I do wrong?

 

Download All
0 Kudos
Message 3 of 6
(2,269 Views)

A LabVIEW array is a so called handle which is really a pointer to a pointer to a datat structure with an int32 per dimension followed by the actual data. Your first C code used pointers to Null terminated strings (not the same as LabVIEW handles -> therefore boom-crash.

Your new approach is even further away from a LabVIEW handle -> again boom-crash. You can however make this work with your new approach by adding an Array to Cluster node after each String to Byfe Array node. Then right click on each and select Cluster Size from the popup menu. In the dialog you see enter the number of elements for that “String” buffer in your struct. Such a cluster is equivalent to the Fixed size array in your struct which gets inlined by the C compiler.

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 6
(2,261 Views)

Your new approach is even further away from a LabVIEW handle -> again boom-crash

Hi Rolf~

thanks for your reply~

you mean that the new structure define is still not adapt with Labview??

so that , what is the correct way to define a structure with char array that can adapted with labview  in C/C++?

thk

struct JUDGE_SPI_PATTERN_DATA_FIXED {
int Data_Group_Count = 0;
int SignBitFirst = 0;
int CondenseMode = 0;
int CaptureCounts = 0;

char Start_Address1[64];
char Start_Address2[64];
char Start_Address3[64];
char Start_Address4[64];
char Start_Address5[64];


char DataString1[128];
char DataString2[128];
char DataString3[128];
char DataString4[128];


char DataMask1[128];
char DataMask2[128];
char DataMask3[128];
char DataMask4[128];
char DataMask5[128];

};

 

0 Kudos
Message 5 of 6
(2,250 Views)
Solution
Accepted by topic author ychch

In my last post I explained to you how to make the LabVIEW diagram to match the configuration for your new attempt. If you insist to instead adapt your C code to what the native LabVIEW cluster from your first attempt (or second their isn't really a big difference), then there is an easy trick. Right click on your Call Library Node and select "Create .c file". Enter a file name to let LabVIEW save the empty function prototype with all its extra necessary definitions to. Open that file and start to learn LabVIEW datatypes when used from C. And don't expect this to be trivial unless you are a really experienced C programmer.

 

Basically such a source code file will include " extcode.h" from the cintools directory in LabVIEW and you will need to link your resulting DLL to labviewv.lib from that folder too in order to call memory manager functions to resize the passed in LabVIEW handles as needed. And functions that call any LabVIEW manager functions won't be executable by any other software than LabVIEW or a build LabVIEW executable.

 

Rolf Kalbermatter
My Blog
Message 6 of 6
(2,234 Views)