05-10-2024 12:45 PM
I am following the tutorial on
Looking at the Returning A Value Array of Integers.vi, it is returning a single integer, not an array.
Solved! Go to Solution.
05-10-2024 01:29 PM
@hekdude wrote:
I am following the tutorial on
Looking at the Returning A Value Array of Integers.vi, it is returning a single integer, not an array.
You didn't read this doc completely.
- When a function returned a pointer and the pointer wasn’t automatically dereferenced.
In these cases, the pointer needs to be dereferenced using either MoveBlock or GetValueByPointer. See:
Dereferencing Pointers from C/C++ DLLs in LabVIEW
But this is really not the best example, to be honest. If I will do that, then better something like that:
Or, alternatively this (it depends, where you want to allocate/resize array):
Then using NumericArrayResize to allocate memory.
05-10-2024 02:52 PM
Thank you for your help. I guess it isn't as easy as I had hoped. Is that the MoveBlock function?
05-11-2024 12:16 AM - edited 05-11-2024 12:35 AM
@hekdude wrote:
Thank you for your help. I guess it isn't as easy as I had hoped. Is that the MoveBlock function?
Oh, it is not very complicated. Let me explain all these methods.
For example, I will fill array in DLL with squares of index.
First method — you allocate array in LabVIEW outside of DLL and pass it as pointer, then source code:
__declspec(dllexport) int __cdecl fnArr(int length, int* arr)
{
if (arr){
for(int i = 0; i < length; i++){
arr[i] = i * i;
}
return 0;
}
else return 1; //indicate an error
}
Good idea at least check pointer.
Now it is called like this:
a little bit more complicated — handle to array outside LabVIEW, but resizing (allocation) inside using LabVIEW Memory Manager:
#include "include/extcode.h"
/* lv_prolog.h and lv_epilog.h set up the correct alignment for LabVIEW data. */
#include "include/lv_prolog.h"
/* Typedefs */
typedef struct {
int32_t dimSize;
int32_t elt[1];
} TD1;
typedef TD1 **TD1Hdl;
#include "include/lv_epilog.h"
__declspec(dllexport) int __cdecl fnLVArr(size_t length, TD1Hdl arr)
{
if(noErr == NumericArrayResize(uL, 1, (UHandle*)(&arr), length)){
(*arr)->dimSize = (int32_t)length;
for(int i = 0; i < length; i++){
(*arr)->elt[i] = i * i;
}
return mgNoErr; // 0
}
else return mgArgErr; // 1
}
Now call looks like this:
Small hint for you — if you don't remember types and typedefs (I don't), LabVIEW can create "Template" for you:
Obviously you can get size from the handle if needed:
Then source looks like this:
__declspec(dllexport) int __cdecl fnLVArr1(TD1Hdl arr)
{
for(int i = 0; i < (*arr)->dimSize; i++){
(*arr)->elt[i] = i * i;
}
return 0;
}
Now back to your question about MoveBlock.
Let say you have allocated array in DLL and returned by pointer:
__declspec(dllexport) int* __cdecl fnLVArr2(size_t length)
{
int* MyArr;
MyArr = (int*)malloc(length * sizeof(int));
//now array allocated outside LabVIEW, remember to free it!
if (MyArr){
for(int i = 0; i < length; i++){
MyArr[i] = i * i;
}
return MyArr;
}
else return NULL;
}
Then to copy memory content between "unmanaged" and "managed" memories you can use MoveBlock:
But I will not recommend this. It is rarely used method, usually if you have third-party DLL and would like to avoid to develop wrapper, or in some other rare cases. For 20+years I'be used this once or may be two times.
Code in attachment, LV2018+CVI2020 both 32- and 64-bits.
Hope it helps.
If you will modify the code, I would like to recommend to save your work before each run, because you can easily crash LabVIEW in case of wrong parameters or incorrect calling conventions, null pointers, out of range errors etc etc. It looks like this (sorry for German Screenshot)
In the crash protocol you will see something like this:
DWarn 0x0E697B77: Caught exception in ExtCode call!
source\execsupp\ExtFuncRunTime.cpp(86) : DWarn 0x0E697B77: Caught exception in ExtCode call!
[ExecSys:0; Executing:"[VI "ArrDemo.vi" (0x00000189f163aca0)]"]minidump id: 69c9b6b2-b6d4-409d-a6c6-5f8283d979c0
DAbort 0x00BA6193:
source\ThEvent.cpp(263) : DAbort 0x00BA6193:
[ExecSys:0; Executing:"[VI "ArrDemo.vi" (0x00000189f163aca0)]"]minidump id: 68f0312e-1971-48a1-9425-cc5b0594afa4
Don't panic, It is OK, just understand the trouble and fix, then it will work.