LabVIEW 中调用动态库接口时,如果是值传递的结构体,可以根据字段拆解为多个参数;如果参数为结构体指针,可用簇(Cluster)来匹配,其内存连续相当于单字节对齐。
1.值传递
接口定义:
typedef struct {
int a;
int b;
} DataA;
void testData1(DataA data, int* a, int* b) {
*a = data.a;
*b = data.b;
}
LabVIEW 函数原型:
LabVIEW 程序框图:
2.指针传递
指针参数可作为输入和输出。接口定义:
typedef struct {
int a;
int b;
} DataA;
void testData2(DataA *data, int* a, int* b) {
*a = data->a;
*b = data->b;
data->a = *b;
data->b = *a;
}
LabVIEW 函数原型:
LabVIEW 程序框图:
3.字节对齐问题
LabVIEW 中簇是内存连续的,相当于单字节对齐,如果动态库的结构体不是单字节对齐那就要在簇中补齐。接口定义:
#pragma pack(4)
typedef struct {
int a;
char b;
int c;
} DataB;
#pragma pack()
void testData3(DataB* data, int* a, char* b , int *c) {
*a = data->a;
*b = data->b;
*c = data->c;
}
LabVIEW 函数原型:
未补齐数值有问题:
字节补齐后结果正常:
4.复杂结构体
以包含字节数组和嵌套结构体为例,数组和结构体成员都可以当作内部组合了另一个簇。接口定义:
typedef struct {
int c;
int d;
} DataSub;
typedef struct {
int a;
char b[20];
DataSub sub;
} DataC;
void testData4(DataC* data) {
data->a = 123;
char arr[] = "COVID-19";
memcpy(data->b, arr, sizeof(arr));
data->sub.c = 2019;
data->sub.d = 2022;
}
LabVIEW 函数原型:
LabVIEW 程序框图:
运行结果:
要注意的就是【数组至簇转换】(Array to Cluster)要自己指定大小(右键菜单),默认 9,最大 256 个元素。
5.用字节数组传递结构体
对于大于 256 个元素的数组,没找到比较简单的转换成簇的方式(LabVIEW 有点反直觉的地方就是数组连到簇里会当作指针),索性我直接把接口按字节数组传递。LabVIEW 用的大端,PC 上一般小端,所以字节和数值转换要翻转一下。接口定义:
typedef struct {
int len;
char arr[1000];
} DataD;
void testData5(DataD* data) {
char info[] = "Hello world!";
data->len = sizeof(info);
memcpy(data->arr, info, data->len);
}
LabVIEW 函数原型:
LabVIEW 程序框图:
运行结果: