LabVIEW 调用库函数生成字符串数组
LabVIEW Call Library Function yielding array of strings
我需要将 C 代码连接到 LabVIEW,我的 C 函数需要返回一个二维字符串数组。我宁愿不被迫提前预先确定数组的大小。所以我想知道,使用什么是正确的数据格式(C 字符串指针数组的句柄?字符串句柄数组的句柄?),如何正确进行分配,以及使用数组参数或return 类型。为 Call Library Function Node 提供的对话框只支持数字类型的数组,所以我有点不知道如何构建它。
你需要 LabVIEW Code Interface Reference Manual 来解决这个问题。
您正在编写一个 C 函数,它将 return 二维字符串数组发送到 LabVIEW。这意味着您需要 returning LabVIEW 的数据结构并使用 LabVIEW 的内存分配器。在您的 C 文件中包含 "extcode.h"(LabVIEW 附带)。然后创建以下 C 代码:
#include "extcode.h"
struct String2DArrayBlock {
int32 dimensionSize1;
int32 dimensionSize2;
LStrHandle stringArray[1]; // Yes, this is intentional. Do not use LStrHandle* because that syntax changes the memory allocation. Old-school C code. LabVIEW's own C++ code has wrappers for managing this with more type safety.
};
typedef String2DArrayBlock** String2DArrayHandle;
MgErr GenerateMyStrings(String2DArrayHandle *ptrToHandle) {
if (!ptrToHandle)
return mgArgErr; // Gotta pass a location for us to allocate.
if (*ptrToHandle) {
// This handle is already allocated. I'm not going to walk you through all the code needed to deallocate.
return mgArgErr;
}
const int32 dimSize1 = ComputeHeight(); // This is your function... whereever your data is coming from.
const int32 dimSize2 = ComputeWidth(); // Same here.
const int32 numberOfElements = dimSize1 * dimSize2;
if (numberOfElements == 0) {
return mgNoErr; // Done. NULL means empty array, and the handle is already NULL.
}
// DSNewHClr allocates the block and flood fills it with all zeros.
*ptrToHandle = (String2DArrayHandle)DSNewHClr(sizeof(String2DArrayBlock) + ((numberOfElements - 1) * sizeof(LStrHandle))); // -1 because the sizeof block has 1 element.
if (!*ptrToHandle)
return mFullErr; // Out of memory
(**ptrToHandle)->dimensionSize1 = dimSize1;
(**ptrToHandle)->dimensionSize2 = dimSize2;
LStrHandle *current = (**ptrToHandle)->stringArray;
for (int32 i = 0; i < numberOfElements; ++i, ++current) {
std::string myCurrentString = GetMyCurrentString(i); // You write this however you look up the individual strings.
if (myCurrentString.empty())
continue; // NULL means empty string
*current = (LStrHandle)DSNewHClr(sizeof(LStr)); // Allocates a zero-length LStrHandle.
if (!*current)
return mFullErr; // The array will be partially filled, but it is in a safe state for early return.
MgErr err = LStrPrintf(*current, (CStr)"%s", myCurrentString.c_str());
if (err)
return err; // The array will be partially filled, but it is in a safe state for early return.
}
return mgNoErr;
}
针对 LabVIEW 运行 时间引擎 (lvrt.dll) 编译您的代码。
在您的 G 代码中,放置一个调用库节点,添加一个参数 "Adapt to type" 和 "Pointers to Handles",并用一个空的二维数组连接它。你完成了。
我需要将 C 代码连接到 LabVIEW,我的 C 函数需要返回一个二维字符串数组。我宁愿不被迫提前预先确定数组的大小。所以我想知道,使用什么是正确的数据格式(C 字符串指针数组的句柄?字符串句柄数组的句柄?),如何正确进行分配,以及使用数组参数或return 类型。为 Call Library Function Node 提供的对话框只支持数字类型的数组,所以我有点不知道如何构建它。
你需要 LabVIEW Code Interface Reference Manual 来解决这个问题。
您正在编写一个 C 函数,它将 return 二维字符串数组发送到 LabVIEW。这意味着您需要 returning LabVIEW 的数据结构并使用 LabVIEW 的内存分配器。在您的 C 文件中包含 "extcode.h"(LabVIEW 附带)。然后创建以下 C 代码:
#include "extcode.h"
struct String2DArrayBlock {
int32 dimensionSize1;
int32 dimensionSize2;
LStrHandle stringArray[1]; // Yes, this is intentional. Do not use LStrHandle* because that syntax changes the memory allocation. Old-school C code. LabVIEW's own C++ code has wrappers for managing this with more type safety.
};
typedef String2DArrayBlock** String2DArrayHandle;
MgErr GenerateMyStrings(String2DArrayHandle *ptrToHandle) {
if (!ptrToHandle)
return mgArgErr; // Gotta pass a location for us to allocate.
if (*ptrToHandle) {
// This handle is already allocated. I'm not going to walk you through all the code needed to deallocate.
return mgArgErr;
}
const int32 dimSize1 = ComputeHeight(); // This is your function... whereever your data is coming from.
const int32 dimSize2 = ComputeWidth(); // Same here.
const int32 numberOfElements = dimSize1 * dimSize2;
if (numberOfElements == 0) {
return mgNoErr; // Done. NULL means empty array, and the handle is already NULL.
}
// DSNewHClr allocates the block and flood fills it with all zeros.
*ptrToHandle = (String2DArrayHandle)DSNewHClr(sizeof(String2DArrayBlock) + ((numberOfElements - 1) * sizeof(LStrHandle))); // -1 because the sizeof block has 1 element.
if (!*ptrToHandle)
return mFullErr; // Out of memory
(**ptrToHandle)->dimensionSize1 = dimSize1;
(**ptrToHandle)->dimensionSize2 = dimSize2;
LStrHandle *current = (**ptrToHandle)->stringArray;
for (int32 i = 0; i < numberOfElements; ++i, ++current) {
std::string myCurrentString = GetMyCurrentString(i); // You write this however you look up the individual strings.
if (myCurrentString.empty())
continue; // NULL means empty string
*current = (LStrHandle)DSNewHClr(sizeof(LStr)); // Allocates a zero-length LStrHandle.
if (!*current)
return mFullErr; // The array will be partially filled, but it is in a safe state for early return.
MgErr err = LStrPrintf(*current, (CStr)"%s", myCurrentString.c_str());
if (err)
return err; // The array will be partially filled, but it is in a safe state for early return.
}
return mgNoErr;
}
针对 LabVIEW 运行 时间引擎 (lvrt.dll) 编译您的代码。
在您的 G 代码中,放置一个调用库节点,添加一个参数 "Adapt to type" 和 "Pointers to Handles",并用一个空的二维数组连接它。你完成了。