ni.com is currently undergoing scheduled maintenance.

Some services may be unavailable at this time. Please contact us for help or try again later.

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,313 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,312 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,283 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,276 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,248 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,237 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,226 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,205 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,199 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,195 Views)