Search the Community
Showing results for tags 'callback'.
-
Hello all, background A while ago I wrote a dll wrapper to get data from dedicated test-hardware. For this hardware there is a dll available. To use this dll you need to use an callback function. If you need to use a dll in Labview which needs a callback you need to write the callback in C code and use a Labview C lib to get the data into Labview, basically my dll takes care of this problem . Enhance the code and way of working more efficient The code I wrote code works fine. However I did not use / test it for hours on a row. And sometimes If I make a mistake when changing the code I run into problems. I was able to fix all the errors and problems however it was not the most efficient way of working. For instance If there is a serious error in the code the dll I need for the hardware can crash, it can make my wrapper crash, which will in return make Labview crash. This makes the way of coding inefficiënt and it will not enable me to read my C++ book etc etc. Example pseudo code I did try to extract some main points of intrest from the code, I did add some comment in the code. I hope someone can give me some general guideline or advice what to read. At this time I am reading: Unhandled C++ exceptions I think I might be able to use it, I did not use this before so advice would be welcome. Thank you all for the help ! // .. // This is a part of the code only intended to have a talk about how to catch errors // It is not complete and intended as Pseudo code // .. int __stdcall MyDriverLoads(const int NumberToInitialise,const bool enableAnotherOption , const char *const path , LVUserEventRef *rwer) { // loads the dll // Q -- I can check if (F_functionname !=0), if it is not 0 then I can proceed if the function returns 0 I can return an error to Labview Extern_dll = Load_Extern_dll(); // Get the functions I need from the dll p2_ExternDriver F_ExternDriver = (p2_ExternDriver)GetProcAddress(Extern_dll, "_ExternDriver"); p2_Initialise F_Initialise = (p2_Initialise)GetProcAddress(Extern_dll, "_Initialise"); p2_AdapterCount F_AdapterCount = (p2_AdapterCount)GetProcAddress(Extern_dll, "_AdapterCount"); p2_StartLogging F_StartLogging = (p2_StartLogging)GetProcAddress(Extern_dll, "_StartLogging"); p2_StopLogging F_StopLogging = (p2_StopLogging)GetProcAddress(Extern_dll, "_StopLogging"); // When there are adapters found I tell it in Labview adapterCount = F_AdapterCount(); // Get the callback function adress, if adress == 0 I can see something is wrong void(__stdcall *p2_CallbackFunction_t) (pt2Obj , const LogData & ) = &CallbackFunction; // Q -- I could use try {} and catch {} however I do not have acces to the source code of the dll so, // I do not know if they used // trow "The Blue error" , or // trow "The Red error" ret = F_ExternDriver(adapterCount, enableLogFile, path, *p2_CallbackFunction_t, pt2Obj); // This tels the dll to start logging before this command you will not receive data in Labview ret F_StartLogging(1,2,3); // Labview is receiving data thats great !!! return ret; // Q -- Labview has been receiving data for a hour what happens if the used extern dll crashes ?? // If the dll crashes when return is passed I can not use try() and catch anymore. // } extern void __stdcall CallbackFunction(pt2Obj , const LogData & ) { // There is a lot to do here // do stuff!! // I did not write everything here err = PostLVUserEvent(*event_ref, &tmpEvent); }
-
Hello I hope someone can help me, I have been trying to get this to work for days but no success yet. What I want to do I got a dll with a wrapper, this dll and wrapper can be used for a special datalogger. The wrapper contains multiple functions, I have got some of them working using a CLFN, for instance I can read a jumper setting from the datalogger in LabView. So far everything is fine. Of course I am not that interested in the jumper setting, I would rather use the datalogger to log data. I need to run one function to start logging. When there is enough data in the databuffer of the driver dll it will call a callback function I need to write in Labview, here is the function which starts the logging as described in the header file: Int LOGEXPORT __sdcall LOG_StartLogging{const char ** logFilename, ptLogCallbackfunction ptFunction, ptObject ptObject} logFilename needs to be a NULL pointer, from my understanding I do not need to do anything with it. Only provide it. If I do not do anything with it some data is saved at a default location. ptLogCallbackfunction, as far as I know I need to provide a pointer to the callback function ptObject ptObject, this must be a void pointer The header also provided how the callback function could look like in 😄 Void __stdcall callbackLog(ptObject object, const int ArraySize, const StructLogdata *const logDataArray) { // copy data from logDataArray for use in my code } StructLogdata is a struct with different datatypes. What I did try I did a search on internet there are some examples about callback functions, most of them point to NET and active X. They use a reg Event Callback. I did read the helpfile at the end of the helpfile there is the text: “Use the Event structure or the Register For Events function to register and handle non-.NET or non-ActiveX events dynamically” I am having a hard time to find a proper example. I did find this site with some information: https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z000000P8XJSA0&l=nl-NL and this one about the refnum: https://forums.ni.com/t5/LabVIEW/Passing-Event-Refnum-to-Call-Library-Function/td-p/4107748 So I did make a user event, I wired a static Vi ref containing a callback vi to the input of this user event. I did wire the user event to a Reg event and wired the event registration refnum to the start logging dll call library function node function pointer input and also to an event structure. I did place a counter in the event structure. But nothing happens besides for an exception which makes Labview crash. The parameters I did use in the call library function are: logFilename: type numeric, datatype: Signed Pointer-sized int Pass: pointer to value ptLogCallbackfunction: type: adapt to type, Data format handles by value (tried all options) ptObject: same as logFilename I did try a lot of different things. Writing them in this post will result in chaos and I don’t want that. I hope someone can help me with a simple example how to make this work, or point me into the correct direction. Thank you all for the help!
-
Hello to you all, Sending a cluster with int's I did manage to send an array with clusters from a dll to Labview. Thank you all for the help. You can find the link here: https://lavag.org/topic/22877-can-someone-help-me-with-an-example-for-an-existing-wrapper-dll-which-uses-function-pointer-with-callback-function/#comment-147496 It works fine I am very pleased with it. 😃 Sending a text string I did got a example here: https://forums.ni.com/t5/Example-Code/Posting-Events-to-a-LabVIEW-Event-Structure-From-a-Dll/ta-p/3996283 Tested it and it works fine. Again I am happy 😃 Sending a cluster with int's AND a string Now I want to send a cluster / struct with a couple of int's AND a string of text. I Got a example of how to send text from a C / C++ wrapper to Labview, can someone please help me out? The thing I do not get is, how to combine the both examples. Is "sizeof(structSample)" valid with a LStrHandle in it? How do I copy the data from the string to the struct, etc. Can someone change the code example or help me with the example so it works? I did add some text to the example code to make it more clear I added +++ signs in my comment in the code. Hope someone can help me. Thanx ! // LVUserEvent.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include <stdio.h> #include "LVUserEvent.h" #define STRING_LENGHT 256 //Can be any size // ++++ I want to send this Cluster/Struct to Labview typedef struct { int firstInt; int secondInt; int thirdInt // +++++ I try to add this, Gues this will not work .. see extcode.h LStrHandle textString[TEXT_STRING_SIZE]; }structSample; typedef struct{ int32_t size; structSample elm[1]; }totalstructSample, **structHdl LVUSEREVENT_API void SendEvent(LVUserEventRef *rwer) { LStrHandle newStringHandle; //Allocate memory for a LabVIEW string handle using LabVIEW's //memory manager functions. newStringHandle=(LStrHandle)DSNewHandle(sizeof(int32)+STRING_LENGHT*sizeof(uChar)); // +++++ OW no another one ... structHdl = (eventHdl)DSNewHandle(sizeof(totalstructSample)); Sleep(2000); PopulateStringHandle(newStringHandle,"+++ Dear int I don't want you in my PostLVUserEvent"); //Post event to Event structure. Refer to "Using External Code //with LabVIEW manual for information about this function. PostLVUserEvent(*rwer,(void *)&newStringHandle); return; } void PopulateStringHandle(LStrHandle lvStringHandle,char* stringData) { //Empties the buffer memset(LStrBuf(*lvStringHandle),'\0',STRING_LENGHT); //Fills the string buffer with stringData sprintf((char*)LStrBuf(*lvStringHandle),"%s",stringData); //Informs the LabVIEW string handle about the size of the size LStrLen(*lvStringHandle)=strlen(stringData); return; }
- 6 replies
-
- postlvuserevent
- dll
-
(and 2 more)
Tagged with:
-
Hello, I am trying to figure out, if it is possible to create a native LabVIEW I/O interface to C/C++ code, that is using the I/O functions through callbacks. The scenario is as follows: I made a toolkit to process multimedia formats and (so far only) video codecs, it is using internally FFmpeg shared objects (DLLs or SOs, further just "DLLs"). They way the FFmpeg DLLs access I/O is through callback mechanism. Following all happens in the wrapper. If I want the toolkit to read data from some I/O like network or disk, I have to create a session, and part of the session are function pointers to callbacks doing various tasks, one of them is reading data. Anytime a user tries to read more data (1 data packet), he forces a call to the session demuxer, that further uses the I/O callback so long, until it parses one packet/hits EOF/corrupt data/etc..., now this works nicely if you want to provide data through standard means like video file or stream URL. Since the capabilities of FFmpeg allow for example (de)muxers and codecs for images, I thought it would be cool to give the user possibility to supply his own data, that he reads via LabVIEW from database or whatever. Not just limit the usage of I/Os implemented inside the DLLs. All I know, is that I cannot use VIs as callbacks inside C/C++ code, so the only way is to somehow "decallback" the implemented I/O mechanism.
-
Hello, I try to make application in LV which will start from TS and will receive callbacks from TS as standard UIMessage. All examples which I found was when LV application started TS and then register callback. This is in “simple UI example”. But I want to lunch panel after sequence in TS was started and then register callbacks. Normally to register callback “Application Manager” is using, but I don’t know how to connect this control to TS context. Also I try to use TS.IEngine obcject and connect this with TS via RunState.Engine but still nothing. Could anyone help me to move next step? This is my simple application example. Thank in advance adn best reagrds. PS: Sorry for my eng.