10-24-2008 11:19 AM
Hello!
Is it possible to Call a Call Library Function Node from DLL's Function?
I mean starting with first CLFN which executes DLL's local function Function1() and Function1 executes second CLFN2 and passes data to LV ?
Solved! Go to Solution.
10-24-2008 11:53 AM
Is this DLL a LabVIEW DLL? If not, I'm not sure why you'd be asking the question in the first place, but assuming it is, then I don't see why you would not be able to do so. The LabVIEW DLL would simply pass the data it got back up to the LabVIEW program.
Is this related to this thread?
10-24-2008 01:51 PM
It should work, just make sure to not create circular references. That could get a bit nasty since Windows can not deal well with that.
Rolf Kalbermatter
10-27-2008 03:28 AM
I'm trying now the following implementation:
And I get an error, could someone point me at a possible point what is incorrect?
typedef struct {
long dimSize;
long elt[1];
} TD1;
typedef TD1 **TD1Hdl;
_declspec(dllexport) void subfunc(int *arr_ind, int *subparam, TD1Hdl *arg1);
_declspec(dllexport) void subfunc(int *arr_ind, int *subparam, TD1Hdl *arg1) {
*arr_ind = 2;
*subparam = 32;
((**arg1)->dimSize) = (*arr_ind)*(sizeof(int32));
((**arg1)->elt[0]) = (*subparam);
}
void localfunc(int *subparam, TD1Hdl *arg1);
void localfunc(int *subparam, TD1Hdl *arg1) {
int *arr_ind = 0;
subfunc( arr_ind,subparam, arg1);
}
_declspec(dllexport) void mainfunc(int *subparam, TD1Hdl *arg1);
_declspec(dllexport) void mainfunc(int *subparam, TD1Hdl *arg1) {
localfunc(subparam, arg1);
}
10-27-2008 04:02 AM
Yes, it's related to that thread. But using string - caused LabView to crash, cause a string is limited in size. So I decided to use an array of strings. 1st function "mainfunc" - executes next one, which executes a chain of local funtions. Each member of this chain - executes subfunc( ) and increases string counter. Subfunc( ) receives data and string counter, allocates space for array by this way: array_size = String_counter * (sizeof(int32)). and passes data to the next array string.
Would the data from previous strings save, or would erase each time Subfunc() executes?
10-27-2008 04:43 AM - edited 10-27-2008 04:50 AM
ACiDuser wrote:I'm trying now the following implementation:
And I get an error, could someone point me at a possible point what is incorrect?
typedef struct {
long dimSize;
long elt[1];
} TD1;
typedef TD1 **TD1Hdl;
_declspec(dllexport) void subfunc(int *arr_ind, int *subparam, TD1Hdl *arg1);
_declspec(dllexport) void subfunc(int *arr_ind, int *subparam, TD1Hdl *arg1) {
*arr_ind = 2;
*subparam = 32;
((**arg1)->dimSize) = (*arr_ind)*(sizeof(int32));
((**arg1)->elt[0]) = (*subparam);
}
You can't do that just like that!! In order to fill in data into a LabVIEW array you properly have to allocate memory for it. You can do that in your DLL by using the function NumericArrayResize(). This is a LabVIEW memory manager function and is required to be called whenever you want to change information in a LabVIEW array (including a string which in fact is simply a byte array) in your C code. Look for the documentation of that function either by googling or in your LabVIEW documentation.
Not that calling LabVIEW manager functions makes the DLL depend on being loaded by a LabVIEW process either the development system or a built application as your DLL will attempt to link back to the function implementation inside the LabVIEW kernel and other processes obviously do not have such a function implemented.
And the dimSize element in a LabVIEW array is not the size in bytes but the size in elements instead!
Rolf Kalbermatter
10-27-2008 08:38 AM
//LabView Array definition
typedef struct {
long dimSize;
long elt[1];
} TD1;
typedef TD1 **TD1Hdl;
//Function which resizes our array each time by One element
void subfunc(int *arr_ind, int *count, TD1Hdl *arg1);
void subfunc(int *arr_ind, int *count, TD1Hdl *arg1) {
NumericArrayResize(iL, 1L,(UHandle*)&(*arg1), (*count) + 1);
(**arg1)->dimSize = (*count) + 1;
((**arg1)->elt[*count])=32;
(*count)++;
}
//Any subfunction for mainfunc()
void localfunc(int *count, TD1Hdl *arg1);
void localfunc(int *count, TD1Hdl *arg1) {
int *arr_ind = 0;
subfunc( arr_ind,count, arg1);
}
// Main function, which starts execution
_declspec(dllexport) void mainfunc(int *count, TD1Hdl arg1);
_declspec(dllexport) void mainfunc(int *count, TD1Hdl arg1) {
*count = 0;
localfunc(count,&arg1);
localfunc(count,&arg1);
localfunc(count,&arg1);
}
This is a working example. The idea was: Main function executes a chain of functions, each performs necessary data processing/execute hardware-specific functions and etc. Every function returns a special message about successfull operation or any error. The aim is to collect those messages in one array of strings and indicate in LabView. This example is for array of signed 32-bit integers, but can be simply modified for array of strings.
The advantage is - that we shouldn't know how many strings we will get and how big array we should resize, this task performs subfunc() routine, which each time resizes the array by one element/string and increments counter.
In the result we get: 32, 32, 32 in array of signed 32-bit integers. Means how many times we call localfunc()
10-27-2008 08:50 AM
10-27-2008 09:19 AM - edited 10-27-2008 09:19 AM
You could now ditch the arr_ind variable altogether as it is not used anymore and then localfunc is simply calling subfunc witht the same parameters and therefore could be ditched as well.
Rolf Kalbermatter
10-27-2008 10:47 AM
I've tried to modify source for Array of strings, It seems to allocate first Array element but when I exit LV - crashes.
typedef struct {
int32 dimSize;
LStrHandle Strings[1];
} LVStringArray;
typedef LVStringArray **LVStrArrayHdl;
void subfunc(int *count, LVStrArrayHdl *in_array);
void subfunc(int *count, LVStrArrayHdl *in_array) {
MgErr error;
int StringLen = 50;
DSSetHandleSize(*in_array, sizeof(int32) + (*count)*sizeof(LStrHandle) );
(***in_array).dimSize = 1;
(***in_array).Strings[0] = (LStrHandle)(DSNewHandle(sizeof(int32) + StringLen*sizeof(uChar)));
(*(***in_array).Strings[0])->cnt=StringLen;
ClearMem((*(***in_array).Strings[0])->str,50);
//sprintf(((*(**in_array)->Strings[*count])->str), "Enter");
}
void localfunc1(int *count, LVStrArrayHdl *in_array);
void localfunc1(int *count, LVStrArrayHdl *in_array) {
subfunc( count, in_array);
}
_declspec(dllexport) void mainfunc(int *count, LVStrArrayHdl in_array);
_declspec(dllexport) void mainfunc(int *count, LVStrArrayHdl in_array) {
*count = 0;
localfunc1(count,&in_array);
localfunc1(count,&in_array);
localfunc1(count,&in_array);
}