jbone Posted January 25, 2011 Report Share Posted January 25, 2011 Hi, I want to create a Labview component that runs some C code. I have been trying with the Call Library Function, and I see it works to write external functions that get and return Labview data. But now, I need to store some internal data in the DLL. And, in case I have more than one CLB component calling to the same functions, the data they are going to use should related to the component that is calling the function. So, does anybody know how can I do it? I have seen there is something called InstanceDataPtr, but what does it contain? how does it work? Can I use it to identify one LV component from the others? I have been trying to find some example using this parameter, but I didn't found any. Thank you very much. Quote Link to comment
jbone Posted January 25, 2011 Author Report Share Posted January 25, 2011 Hi, I want to create a Labview component that runs some C code. I have been trying with the Call Library Function, and I see it works to write external functions that get and return Labview data. But now, I need to store some internal data in the DLL. And, in case I have more than one CLB component calling to the same functions, the data they are going to use should related to the component that is calling the function. So, does anybody know how can I do it? I have seen there is something called InstanceDataPtr, but what does it contain? how does it work? Can I use it to identify one LV component from the others? I have been trying to find some example using this parameter, but I didn't found any. Thank you very much. When I said CLB component, actually I meant CLF (Calling Library Function). And another question... I have read about the possibility of using CINs, but... since they are not supported in LV2010, is there any equivalent method or way of doing what you were able to do with them? Quote Link to comment
mzu Posted January 26, 2011 Report Share Posted January 26, 2011 I have read about the possibility of using CINs, but... since they are not supported in LV2010, is there any equivalent method or way of doing what you were able to do with them? Like what? Since LV 8.2 callbacks are supported by DLLs. I suggest reading my favorite article on the topic: http://expressionflow.com/2007/05/19/external-code-in-labview-part2-comparison-between-shared-libraries-and-cins/. Parts 1 and part 3 are of some interest as well. Quote Link to comment
jbone Posted January 26, 2011 Author Report Share Posted January 26, 2011 (edited) Like what? Since LV 8.2 callbacks are supported by DLLs. I suggest reading my favorite article on the topic: http://expressionflo...ries-and-cins/. Parts 1 and part 3 are of some interest as well. Thanks for the info... that explains exactly what I meant to say: in CINs you could have some data associated to each individual instance and I do not see how to do that with CFL and DLLs. But let me explain my case: I want to make my own LV component that calls some C function that uses an external API. So the first time my function is called, it creates and defines some API's variables and objects and store them. So the future callings of my function do not need to define and create them again. The main problem is that this variables and objects must be different for any instance. I mean: if I have more than one Call Library Function components, calling to my function, running at the same time, I need them to create their own API's variables and objects, instead of sharing them. So I need to be able to access or allocate some space memory for each different instance of the CLF component that calls to my function. How can I do this with Call Library Function? How can I do it with any other possibility? Thank you very much. Edited January 26, 2011 by jbone Quote Link to comment
vugie Posted January 26, 2011 Report Share Posted January 26, 2011 I want to make my own LV component that calls some C function that uses an external API. So the first time my function is called, it creates and defines some API's variables and objects and store them. So the future callings of my function do not need to define and create them again. The main problem is that this variables and objects must be different for any instance. I mean: if I have more than one Call Library Function components, calling to my function, running at the same time, I need them to create their own API's variables and objects, instead of sharing them. So I need to be able to access or allocate some space memory for each different instance of the CLF component that calls to my function. You should identify data stored in DLL with some kind of key or handle. Usually just data pointer casted to integer serves well for this purpose (but it may be also an index within some internal array, key-string within associative array or sth like this). So for example: when function in DLL is asked to store some data it allocates memory for it, put the data there and returns a pointer to that area (as an integer). Calling function must keep that pointer and refer to it each time it wants to do something with stored data. In more advanced case DLL stores a list of pointers it created to keep the track. It gives more control over stored data and helps in fighting with memory leaks. 1 Quote Link to comment
jbone Posted January 26, 2011 Author Report Share Posted January 26, 2011 You should identify data stored in DLL with some kind of key or handle. Usually just data pointer casted to integer serves well for this purpose (but it may be also an index within some internal array, key-string within associative array or sth like this). So for example: when function in DLL is asked to store some data it allocates memory for it, put the data there and returns a pointer to that area (as an integer). Calling function must keep that pointer and refer to it each time it wants to do something with stored data. Ok, I really like that option, because it is the one I started to implement. Thanks very much for the explanation. In more advanced case DLL stores a list of pointers it created to keep the track. It gives more control over stored data and helps in fighting with memory leaks. This part I do not get it... could you, please, explain it a bit deeper or give me some example on how to do this. Or just tell me a good place to read about. Finally, does the Instance Data Pointer anything to do with this purposes? What is it used for? Thank you very much. Quote Link to comment
Rolf Kalbermatter Posted February 4, 2011 Report Share Posted February 4, 2011 Hi, I want to create a Labview component that runs some C code. I have been trying with the Call Library Function, and I see it works to write external functions that get and return Labview data. But now, I need to store some internal data in the DLL. And, in case I have more than one CLB component calling to the same functions, the data they are going to use should related to the component that is calling the function. So, does anybody know how can I do it? I have seen there is something called InstanceDataPtr, but what does it contain? how does it work? Can I use it to identify one LV component from the others? I have been trying to find some example using this parameter, but I didn't found any. Thank you very much. The InstanceDataPtr is basically what the GetDSStorage() and SetDSStorage() functions provided for CINs. It is a pointer value LabVIEW maintains for each Call Library Node in a diagram and in the cases of reentrant VIs with Call Library Nodes for each instance of such a Call Library Node. Your DLL can specifiy the three Callback functions ( I still think the name callback function is a mistake for this functionality) that all accept a reference to this InstanceDataPtr. These three functions Reserve(), Unreserve(), Abort() correspond somewhat to the CIN functions CINInit(), CINDispose(),, and CINAbort(). Usually you would in Reserve() check if the InstanceDataPtr is NULL and create it then or reuse the non-null value. In Unreserve() you should deallocate any resources that you created for this InstanceDataPtr. In Abort() you could for instance cancel any pending IO or other operations associated with this InstanceDataPtr to prevent the threaded Resetting.... dialog when your DLL function hangs on a IO driver call. The actual function associated with the Call Library Node can be configured to have an extra InstanceDataPtr parameter that will be not visible as terminal on the diagram. LabVIEW will pass the data pointer instance stored for the current CLN instance to this parameter. Please note, this is strictly for managing a specific CLN instance. It is not meant to pass around as a token between different CLNs or even different instances of the same CLN in case that the CLN resides in a multiple instantiated reentrant VI. It seems what you want is more a kind of token or handle you can pass between different CLNs to identify some resource. This has to be done by your library for instance by creating a pointer where all the necessary information is stored. You can treat this as opaque value as far as LabVIEW is concerned. Basically you configure the according parameter to be a pointer sized integer and pass this "handle" around in LabVIEW like this between the different CLNs. If you need to access content inside this handle in a LabVIEW diagram your library should export corresponding accessor functions that you can import with CLNs. 2 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.