bsvingen Posted January 19, 2009 Report Share Posted January 19, 2009 Download File:post-4885-1232315590.zipUsing C++ classes in LV is something that pops up now and then. Searching the net is almost fruitless, untill I found this site. I simplified it a bit to better understand what was going on, and called it from LV. I put it here with source and a compiled DLL in case someone else is searching for days to find out how to do this. The clue is of course to built a C wrapper and call it from LV, but that's not the main clue. The main clue is to make the wrapper opaque to the C++ code by typedefing a struct using the class, and pass a pointer to the struct. This way none of the C++ class code need to be touched. I think this can only be done in C++, not in plain C, because C++ doesn't differentiate between classes and structs, and plain C does not have classes. With this wrapper, the C++ classes can be used in principle like any other GOOP classes. Quote Link to comment
crelf Posted January 19, 2009 Report Share Posted January 19, 2009 QUOTE (bsvingen @ Jan 18 2009, 04:55 PM) I simplified it a bit to better understand what was going on, and called it from LV. I put it here with source and a compiled DLL in case someone else is searching for days to find out how to do this. I'd like to see this become a http://wiki.lavag.org/' rel='nofollow' target="_blank">LabVIEWwiki item... Quote Link to comment
Rolf Kalbermatter Posted January 20, 2009 Report Share Posted January 20, 2009 QUOTE (bsvingen @ Jan 18 2009, 04:55 PM) Download File:post-4885-1232315590.zipUsing C++ classes in LV is something that pops up now and then. Searching the net is almost fruitless, untill I found this site. I simplified it a bit to better understand what was going on, and called it from LV. I put it here with source and a compiled DLL in case someone else is searching for days to find out how to do this.The clue is of course to built a C wrapper and call it from LV, but that's not the main clue. The main clue is to make the wrapper opaque to the C++ code by typedefing a struct using the class, and pass a pointer to the struct. This way none of the C++ class code need to be touched. I think this can only be done in C++, not in plain C, because C++ doesn't differentiate between classes and structs, and plain C does not have classes. With this wrapper, the C++ classes can be used in principle like any other GOOP classes. The real reason why you need to compile the wrapper in C++ is that only C++ can resolve the C++ typical things about how to call object methods and access public object variables. A class is in fact a sort of structure but how these things are layed out in memory and organized is something very C++ specific a C compiler can't deal in easily. There are exceptions to this such as COM, where even the binary layout of the C++ object is strictly defined so that given proper C accessor macros you can actually access a COM object both from C and C++, but that is a specific implementation of object classes in an attempt to make them compiler independent. The problem of mutations of the C++ object and the change in possible methods is solved there with the introduction of interface identifiers one has to query with the IUnknown interface and once you have released an interface you can not ever make changes to it but instead need to define a new interface and make that available too through the IUnknown QueryInterface method. For normally defined C++ object classes there is no real standard at all how the objects have to be organized in memory and how various things like virtual methods, inheritance and such are implemented on a binary level. This also makes it very difficult to call C++ link libs from a different compiler than the one who created them. I usually just define a opaque pointer in the wrapper, either void * or something like: struct <name>_t; typedef struct <name>_t *<name> The second does make it a bit more clear in the according function prototype what is meant to happen and requires an explicit cast in the call of any object method or public variable access but I wouldn't see whyyou would have to do any modifications on the original C++ source code at all. As far as LabVIEWs Call library Node is concerned those object pointers are just an uInt32 for me and in LabVIEW 8.6 you would even use the Unsigned Pointer-sized Integer, which will take care to keep your Call Library Node correct if you ever happen to go to a LabVIEW for 64 Bits OS and port your C++ library and wrapper to 64 bit too. Rolf Kalbermatter 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.