LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Returning A Value_Array Of Integers not returning an array when importing the DLL

Solved!
Go to solution

I am following the tutorial on 

https://forums.ni.com/t5/Developer-Center-Resources/Tutorial-Creating-Wrapper-VIs-for-C-C-DLL-functi...

 

Looking at the Returning A Value Array of Integers.vi, it is returning a single integer, not an array.

hekdude_0-1715363059946.png

 

0 Kudos
Message 1 of 4
(792 Views)
Solution
Accepted by topic author hekdude

@hekdude wrote:

I am following the tutorial on 

https://forums.ni.com/t5/Developer-Center-Resources/Tutorial-Creating-Wrapper-VIs-for-C-C-DLL-functi...

 

Looking at the Returning A Value Array of Integers.vi, it is returning a single integer, not an array.

hekdude_0-1715363059946.png

 


You didn't read this doc completely.

 


But this is really not the best example, to be honest. If I will do that, then better something like that:

Screenshot 2024-05-10 20.25.55.png

Or, alternatively this (it depends, where you want to allocate/resize array):

 

Screenshot 2024-05-10 20.26.36.png

Then using NumericArrayResize to allocate memory.

0 Kudos
Message 2 of 4
(778 Views)

Thank you for your help. I guess it isn't as easy as I had hoped. Is that the MoveBlock function?

0 Kudos
Message 3 of 4
(751 Views)

@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:

Screenshot 2024-05-11 07.00.45.png

 

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:

Screenshot 2024-05-11 07.04.13.png

Small hint for you — if you don't remember types and typedefs (I don't), LabVIEW can create "Template" for you:

Screenshot 2024-05-11 06.08.39.png

Obviously you can get size from the handle if needed:

Screenshot 2024-05-11 07.09.04.png

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:

snippet.png

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)

Screenshot 2024-05-11 07.30.54.png

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.

0 Kudos
Message 4 of 4
(675 Views)