The definition of the type is as follows:
/** @brief Long Pascal-style string types. */
typedef struct {
int32 cnt; /* number of bytes that follow */
uChar str[1]; /* cnt bytes */
} LStr, *LStrPtr, **LStrHandle;
typedef struct _LStrArray {
int32 nElts;
LStrHandle str[1];
} LStrArray, **LStrArrayHandle;
Note that the use of 1 is the C technique to make an array type be allocated flat inline instead of in a separate pointer. The same declaration is used regardless of the length of the array or length of the string. You allocate enough memory accommodate the full size of the array/string... indexes deliberately go beyond the declared allocation size. It's something unheard of in managed languages, but this is the low-level structural declaration that the compiler uses.
To invoke from .NET code, you'll need to create a wrapper DLL that takes a flattened form of the data that you marshal across as a string or other marshallable data structure and then unflatten\construct in the C++ code. Both the array handle itself and the internal string handles have to be allocated with DSNewHandle() or DSNewHClr() from the extcode.h header file so that they're in the memory space that LabVIEW can manipulate.
This example shows invoking the DLL from another C DLL, but it has other helpful discussion.
PS: LabVIEW DOES use C calling conventions. That refers to the order of parameters on the stack and the fact that the data structures are all definable with PODs (plain old C data types). It does not imply anything about the data structures used in the interfaces.