Prev: error 200279
Next: CMD.EXE Output Not Showing up
From: lmd2 on 10 Jul 2008 10:40 No, that may not be right, just reading this article <a href="http://zone.ni.com/devzone/cda/tut/p/id/4852" target="_blank">http://zone.ni.com/devzone/cda/tut/p/id/4852</a> , and maybe the event reference gets fed to the wrapper DLL(?) so then what gets fed to the input of client's DLL? back to the drawing board
From: rolfk on 10 Jul 2008 13:40 lmd2 wrote: No, that may not be right, just reading this article <a href="http://zone.ni.com/devzone/cda/tut/p/id/4852" target="_blank">http://zone.ni.com/devzone/cda/tut/p/id/4852</a> , and maybe the event reference gets fed to the wrapper DLL(?) so then what gets fed to the input of client's DLL? back to the drawing boardNo, no! The user event refnum is NOT a callback function pointer! It's the refnm that is passed to PostLVUserEvent() as first parameter. So you will write a DLL which provides the actual callback function, and a second function to be called by LabVIEW to install that callback and possibly to revoke it too, dpending on the DLL.The callback function then calls PostLVUserEvent whenever it is called using the UserEvent refnum that you passed from LabVIEW to the InstallCallback. If your DLL install callback allows passing of a user data item (usually 32 bits) that gets then passed to the callback as extra parameter, you can simply pass the userevent refnum as this user data to the registration function and when your callback function is invoked retrieve that user data and cast it back into the refnum and then invoke PostLVUserEvent().When the registration does not allow for passing a user data item things get a little more difficult since you will have to store the refnum somewhere (like in a global variable) and reference it from the callback function. I'm afraid I can't really explain it more easily than this in conjunction with the example you also found. You are dealing with callbacks, function pointers and such and that are definitely advanced C programming topics. If you can't wrap your head around this you are in good company but it will make it virtually impossible to get this working yourself. Rolf KalbermatterMessage Edited by rolfk on 07-10-2008 07:25 PM
From: lmd2 on 10 Jul 2008 14:10 Let's step back a second. This entire effort is to convert a device driver written in C to LabVIEW. LabVIEW programmers aren't going to be writing callback functions in C anyway, The intent is when one of the interrupts enabled in the mask occurrs, the user can do 'something'. Ideally if one of the interrupts occurrs a LabVIEW programmer will want to run some G code (not C code). What would be ideal is some way to coerce or cast an event reference so that the clients function would accept it, and then simply run some LabVIEW code (say in an event structure) and skip the C function pointer completely? Basically I want to use the clients function which triggers on an interrupt to run something on my block diagram, not really a C function - otherwise how will this be usefull to C-challenged LabVIEW coders
From: rolfk on 10 Jul 2008 14:40 lmd2 wrote: Let's step back a second. This entire effort is to convert a device driver written in C to LabVIEW. LabVIEW programmers aren't going to be writing callback functions in C anyway, The intent is when one of the interrupts enabled in the mask occurrs, the user can do 'something'. Ideally if one of the interrupts occurrs a LabVIEW programmer will want to run some G code (not C code). What would be ideal is some way to coerce or cast an event reference so that the clients function would accept it, and then simply run some LabVIEW code (say in an event structure) and skip the C function pointer completely? Basically I want to use the clients function which triggers on an interrupt to run something on my block diagram, not really a C function - otherwise how will this be usefull to C-challenged LabVIEW codersWell, it would be ideal but basically impossible. LabVIEW simply has not enough information to be able to do such coercion automatically and a configuration dialog that would allow you to tell LabVIEW how to do this right would be an entire magnitued more complicated than the Call Library Node configurationalready is (which would basically mean that only people can understand it that know enough that they would go the C wrapper route anyhow).And your end user is not going to deal with that at all even when you decide to give him the VI library as a development Toolkit. But someone has to do the translation between LabVIEW and C. For simple functions calls this can be done in the Call Library Configuration dialog. For more advanced things you may need to resolve to some tricks in the LabVIEW diagram with data copying such as you have encountered with the cluster/structure already. While you can do this still in LabVIEW it soon gets so complicated that writing a wrapper DLL that translates between the C interface and a more friendly LabVIEW function interface to be called by the Call Library Node is actually getting easier than trying to do yourself all those things that a C compiler normally takes care of automatically.And when callback functions get involved a wrapper DLL is really the only sane solution. Anything else is going to be a nightmare in terms of maintainability of your code And soneone has to write this wrapper DLL. Once it is written all the other users of your VI library won;t even know they are dealing with a C interface. That is after all the whole idea about writing an interface VI library.Basically interfacing to a DLL in LabVIEW can be classified as follows:1) API has simple functions that take only scalar parameters either by reference or value, simple C pointer arrays and strings allocated by the caller. -> easy to interface although it is some work even when using the Import Library Wozard since you have to verify it anyhow afterwards as the Wizard can always create faulty code.2) API with more complicated parameters like structures or callee allocated buffers. -> Still possible to do entirely in LabVIEW but you need to do some serious work on the diagram and a wrapper DLL is soon the better choice if you have more than a few functions that need such translation.3) Adavanced features such as callbacks or functon pointers in general. -> Wrapper DLL is basically unavoidable if you want to stay sane and keep it maintainable.There have been solutions promoted involving LabVIEW created DLLs or .Net remoting but they all have serious drawbacks that make it almost unbearable to support such a solution in the long run.Rolf KalbermatterMessage Edited by rolfk on 07-10-2008 08:22 PM
From: lmd2 on 10 Jul 2008 15:40
ok so I have to learn this found an example "Posting Events to a LabVIEW Event Structure From a Dll" at <a href="http://zone.ni.com/devzone/cda/epd/p/id/1480" target="_blank">http://zone.ni.com/devzone/cda/epd/p/id/1480</a> I'll look this over and try to gain some insight. One thing that still makes no sense to me, I have to wire something into the input of the CLFN for the original function, in my earlier problem (pointer to a pointer to a struct) my dll allocates a block of memory, returns the address which then gets passed to the client's dll. In this case what if anything gets passed to the clients dll? |