LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Interopterability: Calling PeakD in lvanlys.dll

Solved!
Go to solution

Hello,

 

So I have been trying and trying to get two different parts of my project working together, and right now this involves calling a LabVIEW analysis function (namely, PeakD) in a C/C++ executable. I have made sure to include all necessary header files from the resource folder and define all relevant structs, in addition to reading about the TD1/TD2 data types and the prototype header but I still cannot figure out what I am doing wrong! Here is the code I have written:

 

 

 

// PeakD.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <stdio.h> #include <windows.h> #include "extcode.h"/* Typedefs */typedef struct { long dimSize; double elt[1];} TD2;typedef TD2 **TD2Hdl;typedef struct { TD2Hdl Input_Array; double Threshold; long Width; unsigned long PeaksValleys; TD2Hdl Peak_Locations; TD2Hdl Peak_Amplitudes; TD2Hdl Peak_Second_Derivatives; long elt8; long elt9;} TD1;typedef struct { long Span; long Index; long NHistoryPts; long Len; long PrevSign; long unused; unsigned long RinvQtPointer; unsigned long FitBufferPointer; unsigned long HistoryPointer; unsigned long PrevCoeffPointer; unsigned long DataPointer; unsigned long slackForRinvQt; unsigned long slackForFitBuffer; unsigned long slackForHistory; unsigned long slackForPrevCoeff; unsigned long slackForData;} TD3;/* Prototypes */typedef void (*MYPROC)(TD1 *PeakApp, TD3 *pPEAKINT, TD2Hdl *SavedData, long *pErr);void _tmain(int argc, _TCHAR* argv[]){ // File: RUNTIME.C // Sample code that uses LoadLibrary and GetProcAddress to access myFunction from MYDLL.DLL. // You will need to include stdio.h and windows.h in your project to use this code HINSTANCE hinstLib; MYPROC ProcAdd; BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; // Get a handle to the DLL module. hinstLib = LoadLibrary(_T("lvanlys")); // Function inputs. TD1 *PeakApp = 0; TD3 *pPEAKINT = 0; TD2Hdl *SavedData = 0; long *pErr = 0; PeakApp = new TD1; pPEAKINT = new TD3; SavedData = new TD2Hdl; pErr = new long; PeakApp->Input_Array[0]->dimSize = 1; PeakApp->Input_Array[0]->elt[0] = 1; PeakApp->Threshold = 10; // Between 0 and 60 PeakApp->Width = 10; // 0 is Peaks, 1 is Valleys PeakApp->PeaksValleys = 0; // Process the beginning of data PeakApp->elt8 = 1; // Process the end of data PeakApp->elt9 = 1; // If the handle is valid, try to get the function address. if (hinstLib != NULL) { ProcAdd = (MYPROC) GetProcAddress(hinstLib, "PeakD"); // If the function address is valid, call the function. if (fRunTimeLinkSuccess = (ProcAdd != NULL)) //(ProcAdd) ("message via DLL function\n"); (ProcAdd) (PeakApp, pPEAKINT, SavedData, pErr); // Free the DLL module fFreeResult = FreeLibrary(hinstLib); } // If unable to call the DLL function, use an alternative if (! fRunTimeLinkSuccess) printf("message via alternative method\n"); }

 

I am supposed to pass pointers (or more specifically, handles) to the "NI Data Objects" which have a long which signifies the size (dim_size) and the rest of the elements (in elt[]). LabVIEW 8 shows this function's prototype and the necessary pointers as being:

 

typedef long (*MYPROC)(void *PeakApp, void *pPEAKINT, Array1DDouble ***SavedData, long *pErr);

 

 

Does this mean that I have to manually cast my integer-based pointer into a (void*) when entering MYPROC (PeakD)? This hasn't worked for me so far, so I'm assuming that the problem lies with my data structures. Anyways, I would greatly appreciate your help on this matter, thanks.

 

~Ali 

0 Kudos
Message 1 of 11
(4,189 Views)
Ugh, the "Insert Code" snippet just ruined the indent and formatting of my last post, so I have attached PeakD.cpp here for the sake of clarity.
0 Kudos
Message 2 of 11
(4,188 Views)

Hi OfMagnitude,

 

I am a little confused with your application. Where is the PeakD integer?

 

thanks

FLash

National Instruments
Applications Engineer
0 Kudos
Message 3 of 11
(4,159 Views)

Thanks for your reply Flash. PeakD() is actually a function, let me copy and paste the exact NI Data types from LabView 8's "Call Library Function" window:

 

long PeakD(Array1DDouble **y, Array1DDouble **x, Array1DDouble **weight, Array1DDouble **lambda, double p, double *merit);

 

I was originally calling the version from LabVIEW 7's lvanlys.dll (which explains why I had a different number of arguments). But basically, Array1DDouble is a handle to the array's data, which I've read that includes a long (for element size) and then the actual data (which is stored in an array). Can someone please confirm this with me, and help me to link to this function? 

0 Kudos
Message 4 of 11
(4,152 Views)

Looks like your "prototype" only applies WITHIN LabVIEW/CVI ITSELF, i.e., your documentation neglects to account for actual C data structs (or clusters as you call them). Care to explain this to me? 

 

PeakD Prototype.PNG

0 Kudos
Message 5 of 11
(4,124 Views)

I have declared all of my structs properly, and I am allocating my handles on the heap using DSNewHandle instead of malloc: 

 

// use DSNewHandle instead of malloc to allocate memory

handle_var = (TD1**)DSNewHandle(sizeof(TD1));

 

Is there any solid reference material for these TD1/TD2/TD3 structures, for the plethora of LabVIEW analysis functions that are available?

0 Kudos
Message 6 of 11
(4,113 Views)

Hi OfMagnitude,

 

I am not completely sure that these functions are open to the public. I will have to get back to you.

 

FLash

National Instruments
Applications Engineer
0 Kudos
Message 7 of 11
(4,102 Views)

Hi OfMagnitude,

I confirmed with our R&D that using this DLL as a standalone outside of LabVIEW is not supported. You are free to work on it yourself but we cannot provide support on it. Sorry.

 

FLash

National Instruments
Applications Engineer
0 Kudos
Message 8 of 11
(4,081 Views)
Okay, well if I am not allowed to link to this function externally, then do you mind at least telling me what this PeakD does  fundamentally (is it a Polynomial, B-Spline or other type of non-linear or least-squares fit)? At least then I can attempt to write some kind of equivalent to be able to use in my C program.
0 Kudos
Message 9 of 11
(4,075 Views)
Solution
Accepted by topic author OfMagnitude

The PeakD function is called by Peak Detector.vi and there is a description of the algorithm in that function's help.

 

Since you must have LabVIEW in order to have the lvanlys.dll, it would be pretty simple to make a dll from the LabVIEW VI itself.

0 Kudos
Message 10 of 11
(4,071 Views)