<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://labviewwiki.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bsvingen</id>
	<title>LabVIEW Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://labviewwiki.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bsvingen"/>
	<link rel="alternate" type="text/html" href="https://labviewwiki.org/wiki/Special:Contributions/Bsvingen"/>
	<updated>2026-04-22T11:46:28Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://labviewwiki.org/w/index.php?title=GOOP_-_Graphical_Object_Oriented_Programming&amp;diff=3988</id>
		<title>GOOP - Graphical Object Oriented Programming</title>
		<link rel="alternate" type="text/html" href="https://labviewwiki.org/w/index.php?title=GOOP_-_Graphical_Object_Oriented_Programming&amp;diff=3988"/>
		<updated>2009-02-11T00:08:13Z</updated>

		<summary type="html">&lt;p&gt;Bsvingen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== GOOP - Graphical Object Oriented Programming  ==&lt;br /&gt;
&lt;br /&gt;
GOOP stands for Graphical Object Oriented Programming. It is a category of frameworks for non-native object-oriented programming in LabVIEW that support by reference objects with VI methods for operating on data. Some versions of GOOP support inheritance and dynamic dispatch. GOOP really hit mainstream with the release of the [http://zone.ni.com/devzone/cda/tut/p/id/3391#3 GOOP Toolkit] from [http://www.endevo.se/ Endevo] and [[National Instruments]]. OpenG even has its own version of GOOP, called [[OpenGOOP]]. &lt;br /&gt;
&lt;br /&gt;
With LVOOP and queues, it is very easy to create basic GOOP&amp;amp;nbsp;functionality. Examples are included in the example folder installed with LabVIEW. &lt;br /&gt;
&lt;br /&gt;
GOOP is great because it allows you to build components that encapsulate their data, functionality, and behavior. Why ecapsulate?... &lt;br /&gt;
&lt;br /&gt;
=== Benefits of Encapsulation  ===&lt;br /&gt;
&lt;br /&gt;
*Maintainable &lt;br /&gt;
*Scalable &lt;br /&gt;
*Useable (and therefore Reusable) &lt;br /&gt;
*Testable &lt;br /&gt;
*Enable Multiple Developer Collaboration&lt;br /&gt;
&lt;br /&gt;
=== See Also  ===&lt;br /&gt;
&lt;br /&gt;
{{Portal|GOOP}} &lt;br /&gt;
&lt;br /&gt;
*[[DqGOOP]] &lt;br /&gt;
*[[GOOP History by Mattias Ericsson]] &lt;br /&gt;
*[[OpenGOOP]]&lt;br /&gt;
&lt;br /&gt;
=== External Links  ===&lt;br /&gt;
&lt;br /&gt;
*[http://zone.ni.com/devzone/conceptd.nsf/appnotebynumber/1A7B60096CE0CDA986256A9A0074E4EC?OpenDocument&amp;amp;node=dz52000_us App Note 143] – Graphical Object Oriented Programming (Jorgen Jehander) &lt;br /&gt;
*[http://zone.ni.com/devzone/devzoneweb.nsf/Opendoc?openagent&amp;amp;958B0EEC7BE032B986256863000A6B64 Graphical Object-Oriented Programming with LabVIEW] – NI Week 1999 Presentation by Jörgen Jehander and Stepan Riha &lt;br /&gt;
*[http://zone.ni.com/devzone/conceptd.nsf/2d17d611efb58b22862567a9006ffe76/5d7db42c91f392fc86256aae00463d78?OpenDocument#3Download Download GOOP Toolkits] from NI &lt;br /&gt;
*[http://sine.ni.com/apps/we/niepd_web_display.display_epd4?p_guid=B45EACE3EB6B56A4E034080020E74861&amp;amp;p_node=DZ52067&amp;amp;p_source=external Object-Oriented Techniques in LabVIEW] – Pure G examples from LV 4.1 &lt;br /&gt;
*[http://www.endevo.se/ Endevo] - the company that supports/develops the GOOP Toolkit &lt;br /&gt;
*GOOP/G++ - Robert Burke&#039;s Web Page&lt;br /&gt;
&lt;br /&gt;
[[Category:GOOP]]&lt;/div&gt;</summary>
		<author><name>Bsvingen</name></author>
	</entry>
	<entry>
		<id>https://labviewwiki.org/w/index.php?title=DLL/shared_library&amp;diff=3965</id>
		<title>DLL/shared library</title>
		<link rel="alternate" type="text/html" href="https://labviewwiki.org/w/index.php?title=DLL/shared_library&amp;diff=3965"/>
		<updated>2009-02-09T17:39:43Z</updated>

		<summary type="html">&lt;p&gt;Bsvingen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= General  =&lt;br /&gt;
&lt;br /&gt;
The first question would be if you really need to do this. While it is a powerful tool it is also tedious work to have to interface to external code through DLLs/shared libraries. &lt;br /&gt;
&lt;br /&gt;
For the rest of this text I will refer to shared libraries but this should be always read to mean DLLs too, which is the term Windows uses for shared libraries. &lt;br /&gt;
&lt;br /&gt;
With the Import Library Wizard in LabVIEW 8.2 a lot of the actual work of interfacing has been automated but this is just an automatic tool and it can not do everything for you. Especially for more complex shared library interfaces it simply has to fail for particular functions and those are also the ones that are likely to take up hours and hours of fiddling, testing and learning about how a C compiler actually puts variables into memory. &lt;br /&gt;
&lt;br /&gt;
The shared library interface in all OSes so far was designed for and around what C needs and can provide. Therefore one needs to know some basic principles about C and for more complex interfaces also relatively intimate knowledge about how a C compiler actually puts up things in memory and such. This is a very steep learning curve for someone not already familiar with C. &lt;br /&gt;
&lt;br /&gt;
An extra difficulty is that the shared library interface has none of the more modern features like automatic type checking and parameter validation like what ActiveX and .Net provide for instance. This means that one single error in the configuration of the Call Library Node or a bug in the shared library itself can and usually will have fatal consequences sooner or later. This can in the best case show as a Protection fault error dialog at runtime of that function, but can also cause so subtle damage that LabVIEW will only crash at some later point when trying to access information that was destroyed earlier on. One possibility is for instance that it will often crash when you try to close LabVIEW since it tries to deallocate resources that have been destroyed by a misbehaving shared library or configuration thereof earlier on. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= C++  =&lt;br /&gt;
&lt;br /&gt;
Calling C++ classes from LabVIEW can sometimes be useful. For instance, when you would like to use a special mathematical/scientific library that is written in C++. However, since LabVIEW&amp;amp;nbsp;only can call DLLs written in plain C, a wrapper must be made that &amp;quot;translates&amp;quot; the C++ classes to ordinary C function calls. This means that you have to write some C code that LabVIEW understands, to indirectly call the C++ classes that LabVIEW&amp;amp;nbsp;doesn&#039;t understand. Since calling C++ classes from C is a rather odd thing to do,&amp;amp;nbsp;there is almost no references to this on the internet (you would rather normally use C++ to call C++ classes),. &lt;br /&gt;
&lt;br /&gt;
Fortunately the wrappers are strightforward to code. There is no need to touch any of the&amp;amp;nbsp;C++ code either,&amp;amp;nbsp;by making the C++ classes &#039;&#039;opaque&#039;&#039;. What you end up with is objects that behave exactly like GOOP objects, only they are made in C++. &lt;br /&gt;
&lt;br /&gt;
The wrappers must be compiled with a C++ compiler, since an ordinary C compiler will not do the trick making the classes&amp;amp;nbsp;opaque. In C++ a struct IS a class, so making the classes opaque is simply a matter of typedef&#039;ing the class to a struct with the same name. Making the function calls C calls instead of C++ calls is done by the extern &amp;quot;C&amp;quot; directive. &lt;br /&gt;
&lt;br /&gt;
Below is a very simple example&amp;amp;nbsp; that shows the principle. It can also be downloaded with source and a LabVIEW vi here: [http://forums.lavag.org/C-classes-from-LV-t12905.html forums.lavag.org/C-classes-from-LV-t12905.html]. In the real world, the most difficult part may be to &amp;quot;translate&amp;quot; LabVIEW types to C types and/or the other way around, as is the main problem with ordinary DLLs. Any such translation&amp;amp;nbsp;must also be handled by the wrapper and/or the vi. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The header file for the C++ class base_class.h and the classes themselves in base_class.cpp: &lt;br /&gt;
&amp;lt;pre&amp;gt;#ifndef _BASE_CLASS_H_&lt;br /&gt;
#define _BASE_CLASS_H_&lt;br /&gt;
&lt;br /&gt;
class base&lt;br /&gt;
{&lt;br /&gt;
   public:&lt;br /&gt;
      base(double x_in);&lt;br /&gt;
      virtual ~base(void);&lt;br /&gt;
      void set_x(double x_in);&lt;br /&gt;
      void get_x(double* x_out);&lt;br /&gt;
      void sqr_x(void);&lt;br /&gt;
&lt;br /&gt;
   private:&lt;br /&gt;
      double x;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* _BASE_CLASS_H_ */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The base_class.cpp (the classes) &lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;base_class.h&amp;quot;&lt;br /&gt;
#include &amp;amp;lt;windows.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
base::base(double x_in)&lt;br /&gt;
   {&lt;br /&gt;
      x = x_in;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
base::~base ()&lt;br /&gt;
   {&lt;br /&gt;
      /* clean up */&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
void base::set_x(double x_in)&lt;br /&gt;
   {&lt;br /&gt;
      x = x_in;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
void base::get_x(double* x_out)&lt;br /&gt;
   {&lt;br /&gt;
      *x_out = x;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
void base::sqr_x(void)&lt;br /&gt;
   {&lt;br /&gt;
      x*=x;&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The header file for the DLL wrapper, c_dll_wrapper.h &lt;br /&gt;
&amp;lt;pre&amp;gt;#ifndef _C_DLL_WRAPPER_H_&lt;br /&gt;
#define _C_DLL_WRAPPER_H_&lt;br /&gt;
&lt;br /&gt;
/* building a DLL */&lt;br /&gt;
#define DLLIMPORT __declspec (dllexport)&lt;br /&gt;
&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
   extern &amp;quot;C&amp;quot; { /* using a C++ compiler */&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
   typedef struct base base; /* make the class opaque to the wrapper */&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT base* create_base(double x_in);&lt;br /&gt;
   DLLIMPORT void set_x(base* LV_ref, double x_in);&lt;br /&gt;
   DLLIMPORT void get_x(base* LV_ref, double* x_out);&lt;br /&gt;
   DLLIMPORT void destroy_base(base* LV_ref);&lt;br /&gt;
   DLLIMPORT void sqr_x(base* LV_ref);&lt;br /&gt;
&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
   }&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#endif /* _C_DLL_WRAPPER_H_ */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the wrapper itself, c_dll_wrapper.cpp &lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;c_dll_wrapper.h&amp;quot;&lt;br /&gt;
#include &amp;quot;base_class.h&amp;quot;&lt;br /&gt;
#include &amp;amp;lt;windows.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT base* create_base(double x_in)&lt;br /&gt;
   {&lt;br /&gt;
      return new base(x_in);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void set_x(base* LV_ref, double x_in)&lt;br /&gt;
   {&lt;br /&gt;
      LV_ref-&amp;amp;gt;set_x(x_in);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void get_x(base* LV_ref, double* x_out)&lt;br /&gt;
   {&lt;br /&gt;
      LV_ref-&amp;amp;gt;get_x(x_out);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void destroy_base(base* LV_ref)&lt;br /&gt;
   {&lt;br /&gt;
      delete LV_ref;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void sqr_x(base* LV_ref)&lt;br /&gt;
   {&lt;br /&gt;
      LV_ref-&amp;amp;gt;sqr_x();&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* The rest must be included in any DLL, and is not part of the wrapper */&lt;br /&gt;
&lt;br /&gt;
BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,&lt;br /&gt;
                       DWORD reason /* Reason this function is being called. */ ,&lt;br /&gt;
                       LPVOID reserved /* Not used. */ )&lt;br /&gt;
{&lt;br /&gt;
   switch (reason)&lt;br /&gt;
   {&lt;br /&gt;
      case DLL_PROCESS_ATTACH:&lt;br /&gt;
         break;&lt;br /&gt;
      case DLL_PROCESS_DETACH:&lt;br /&gt;
         break;&lt;br /&gt;
       case DLL_THREAD_ATTACH:&lt;br /&gt;
         break;&lt;br /&gt;
      case DLL_THREAD_DETACH:&lt;br /&gt;
         break;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Returns TRUE on success, FALSE on failure */&lt;br /&gt;
   return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bsvingen</name></author>
	</entry>
	<entry>
		<id>https://labviewwiki.org/w/index.php?title=DLL/shared_library&amp;diff=3944</id>
		<title>DLL/shared library</title>
		<link rel="alternate" type="text/html" href="https://labviewwiki.org/w/index.php?title=DLL/shared_library&amp;diff=3944"/>
		<updated>2009-02-08T22:18:00Z</updated>

		<summary type="html">&lt;p&gt;Bsvingen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= General  =&lt;br /&gt;
&lt;br /&gt;
The first question would be if you really need to do this. While it is a powerful tool it is also tedious work to have to interface to external code through DLLs/shared libraries. &lt;br /&gt;
&lt;br /&gt;
For the rest of this text I will refer to shared libraries but this should be always read to mean DLLs too, which is the term Windows uses for shared libraries. &lt;br /&gt;
&lt;br /&gt;
With the Import Library Wizard in LabVIEW 8.2 a lot of the actual work of interfacing has been automated but this is just an automatic tool and it can not do everything for you. Especially for more complex shared library interfaces it simply has to fail for particular functions and those are also the ones that are likely to take up hours and hours of fiddling, testing and learning about how a C compiler actually puts variables into memory. &lt;br /&gt;
&lt;br /&gt;
The shared library interface in all OSes so far was designed for and around what C needs and can provide. Therefore one needs to know some basic principles about C and for more complex interfaces also relatively intimate knowledge about how a C compiler actually puts up things in memory and such. This is a very steep learning curve for someone not already familiar with C. &lt;br /&gt;
&lt;br /&gt;
An extra difficulty is that the shared library interface has none of the more modern features like automatic type checking and parameter validation like what ActiveX and .Net provide for instance. This means that one single error in the configuration of the Call Library Node or a bug in the shared library itself can and usually will have fatal consequences sooner or later. This can in the best case show as a Protection fault error dialog at runtime of that function, but can also cause so subtle damage that LabVIEW will only crash at some later point when trying to access information that was destroyed earlier on. One possibility is for instance that it will often crash when you try to close LabVIEW since it tries to deallocate resources that have been destroyed by a misbehaving shared library or configuration thereof earlier on. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= C++  =&lt;br /&gt;
&lt;br /&gt;
Calling C++ classes from LabVIEW can sometimes be useful. For instance, when you would like to use a special mathematical/scientific library that is written in C++. However, since LabVIEW&amp;amp;nbsp;only can call DLLs written in plain C, a wrapper must be made that &amp;quot;translate&amp;quot; the C++ classes to C function calls. This means that you have to write some C code that LabVIEW understands, to indirectly call the C++ classes that LabVIEW&amp;amp;nbsp;doesn&#039;t understand. Since calling C++ classes from C is a rather odd thing to do (you would rather simply use C++ to call C++ classes), there is almost no references to this on the internet. &lt;br /&gt;
&lt;br /&gt;
Fortunately the wrappers are strightforward to code, and the C++ code doesn&#039;t need to be touched at all by making the C++ classes opaque. What you end up with is objects exactly like GOOP where you get a reference to them, only they are made in C++. &lt;br /&gt;
&lt;br /&gt;
The wrappers must be compiled with a C++ compiler, since this is the only way to make them opaque. In C++ a struct IS a class, so making the classes opaque is simply a matter of typedef&#039;ing the class. Making the function calls C calls instead of C++ calls is done by the extern C directive. &lt;br /&gt;
&lt;br /&gt;
Below is a very simple example&amp;amp;nbsp; that shows the priciple. It can also be downloaded with source and LabVIEW vi here: [http://forums.lavag.org/C-classes-from-LV-t12905.html forums.lavag.org/C-classes-from-LV-t12905.html]. In the real world, the most difficult part may be to &amp;quot;translate&amp;quot; LabVIEW types to C types and/or the other way around, as with ordinary DLLs. This must also be handled by the wrapper. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The header file for the C++ class base_class.h and the classes themselves in base_class.cpp: &lt;br /&gt;
&amp;lt;pre&amp;gt;#ifndef _BASE_CLASS_H_&lt;br /&gt;
#define _BASE_CLASS_H_&lt;br /&gt;
&lt;br /&gt;
class base&lt;br /&gt;
{&lt;br /&gt;
   public:&lt;br /&gt;
      base(double x_in);&lt;br /&gt;
      virtual ~base(void);&lt;br /&gt;
      void set_x(double x_in);&lt;br /&gt;
      void get_x(double* x_out);&lt;br /&gt;
      void sqr_x(void);&lt;br /&gt;
&lt;br /&gt;
   private:&lt;br /&gt;
      double x;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* _BASE_CLASS_H_ */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The base_class.cpp (the classes) &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;base_class.h&amp;quot;&lt;br /&gt;
#include &amp;amp;lt;windows.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
base::base(double x_in)&lt;br /&gt;
   {&lt;br /&gt;
      x = x_in;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
base::~base ()&lt;br /&gt;
   {&lt;br /&gt;
      /* clean up */&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
void base::set_x(double x_in)&lt;br /&gt;
   {&lt;br /&gt;
      x = x_in;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
void base::get_x(double* x_out)&lt;br /&gt;
   {&lt;br /&gt;
      *x_out = x;}&lt;br /&gt;
&lt;br /&gt;
void base::sqr_x(void)&lt;br /&gt;
{&lt;br /&gt;
   x*=x;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;The header file for the wrapper c_dll_wrapper.h &lt;br /&gt;
&amp;lt;pre&amp;gt;#ifndef _C_DLL_WRAPPER_H_&lt;br /&gt;
#define _C_DLL_WRAPPER_H_&lt;br /&gt;
&lt;br /&gt;
/* building a DLL */&lt;br /&gt;
#define DLLIMPORT __declspec (dllexport)&lt;br /&gt;
&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
   extern &amp;quot;C&amp;quot; { /* using a C++ compiler */&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
   typedef struct base base; /* make the class opaque to the wrapper */&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT base* create_base(double x_in);&lt;br /&gt;
   DLLIMPORT void set_x(base* LV_ref, double x_in);&lt;br /&gt;
   DLLIMPORT void get_x(base* LV_ref, double* x_out);&lt;br /&gt;
   DLLIMPORT void destroy_base(base* LV_ref);&lt;br /&gt;
   DLLIMPORT void sqr_x(base* LV_ref);&lt;br /&gt;
&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
   }&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#endif /* _C_DLL_WRAPPER_H_ */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the wrapper itself, c_dll_wrapper.cpp &lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;c_dll_wrapper.h&amp;quot;&lt;br /&gt;
#include &amp;quot;base_class.h&amp;quot;&lt;br /&gt;
#include &amp;amp;lt;windows.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT base* create_base(double x_in)&lt;br /&gt;
   {&lt;br /&gt;
      return new base(x_in);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void set_x(base* LV_ref, double x_in)&lt;br /&gt;
   {&lt;br /&gt;
      LV_ref-&amp;amp;gt;set_x(x_in);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void get_x(base* LV_ref, double* x_out)&lt;br /&gt;
   {&lt;br /&gt;
      LV_ref-&amp;amp;gt;get_x(x_out);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void destroy_base(base* LV_ref)&lt;br /&gt;
   {&lt;br /&gt;
      delete LV_ref;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void sqr_x(base* LV_ref)&lt;br /&gt;
   {&lt;br /&gt;
      LV_ref-&amp;amp;gt;sqr_x();&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,&lt;br /&gt;
                       DWORD reason /* Reason this function is being called. */ ,&lt;br /&gt;
                       LPVOID reserved /* Not used. */ )&lt;br /&gt;
{&lt;br /&gt;
   switch (reason)&lt;br /&gt;
   {&lt;br /&gt;
      case DLL_PROCESS_ATTACH:&lt;br /&gt;
         break;&lt;br /&gt;
      case DLL_PROCESS_DETACH:&lt;br /&gt;
         break;&lt;br /&gt;
       case DLL_THREAD_ATTACH:&lt;br /&gt;
         break;&lt;br /&gt;
      case DLL_THREAD_DETACH:&lt;br /&gt;
         break;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Returns TRUE on success, FALSE on failure */&lt;br /&gt;
   return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bsvingen</name></author>
	</entry>
	<entry>
		<id>https://labviewwiki.org/w/index.php?title=DLL/shared_library&amp;diff=3943</id>
		<title>DLL/shared library</title>
		<link rel="alternate" type="text/html" href="https://labviewwiki.org/w/index.php?title=DLL/shared_library&amp;diff=3943"/>
		<updated>2009-02-08T22:05:25Z</updated>

		<summary type="html">&lt;p&gt;Bsvingen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= General  =&lt;br /&gt;
&lt;br /&gt;
The first question would be if you really need to do this. While it is a powerful tool it is also tedious work to have to interface to external code through DLLs/shared libraries. &lt;br /&gt;
&lt;br /&gt;
For the rest of this text I will refer to shared libraries but this should be always read to mean DLLs too, which is the term Windows uses for shared libraries. &lt;br /&gt;
&lt;br /&gt;
With the Import Library Wizard in LabVIEW 8.2 a lot of the actual work of interfacing has been automated but this is just an automatic tool and it can not do everything for you. Especially for more complex shared library interfaces it simply has to fail for particular functions and those are also the ones that are likely to take up hours and hours of fiddling, testing and learning about how a C compiler actually puts variables into memory. &lt;br /&gt;
&lt;br /&gt;
The shared library interface in all OSes so far was designed for and around what C needs and can provide. Therefore one needs to know some basic principles about C and for more complex interfaces also relatively intimate knowledge about how a C compiler actually puts up things in memory and such. This is a very steep learning curve for someone not already familiar with C. &lt;br /&gt;
&lt;br /&gt;
An extra difficulty is that the shared library interface has none of the more modern features like automatic type checking and parameter validation like what ActiveX and .Net provide for instance. This means that one single error in the configuration of the Call Library Node or a bug in the shared library itself can and usually will have fatal consequences sooner or later. This can in the best case show as a Protection fault error dialog at runtime of that function, but can also cause so subtle damage that LabVIEW will only crash at some later point when trying to access information that was destroyed earlier on. One possibility is for instance that it will often crash when you try to close LabVIEW since it tries to deallocate resources that have been destroyed by a misbehaving shared library or configuration thereof earlier on. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= C++  =&lt;br /&gt;
&lt;br /&gt;
Calling C++ classes from LabVIEW can sometimes be useful. For instance, when you would like to use a special mathematical/scientific library that is written in C++. However, since LabVIEW&amp;amp;nbsp;only can call DLLs written in plain C, a wrapper must be made that &amp;quot;translate&amp;quot; the C++ classes to C function calls. This means that you have to write some C code that LabVIEW understands, to indirectly call the C++ classes that LabVIEW&amp;amp;nbsp;doesn&#039;t understand. Since calling C++ classes from C is a rather odd thing to do (you would rather simply use C++ to call C++ classes), there is almost no references to this on the internet. &lt;br /&gt;
&lt;br /&gt;
Fortunately the wrappers are strightforward to code, and the C++ code doesn&#039;t need to be touched at all by making the C++ classes opaque. What you end up with is objects exactly like GOOP where you get a reference to them, only they are made in C++. &lt;br /&gt;
&lt;br /&gt;
The wrappers must be compiled with a C++ compiler, since this is the only way to make them opaque. In C++ a struct IS a class, so making the classes opaque is simply a matter of typedef&#039;ing the class. Making the function calls C calls instead of C++ calls is done by the extern C directive. &lt;br /&gt;
&lt;br /&gt;
Below is a very simple example&amp;amp;nbsp; that shows the priciple. It can also be downloaded with source and LabVIEW vi here: [http://forums.lavag.org/C-classes-from-LV-t12905.html forums.lavag.org/C-classes-from-LV-t12905.html]. In the real world, the most difficult part may be to &amp;quot;translate&amp;quot; LabVIEW types to C types and/or the other way around, as with ordinary DLLs. This must also be handled by the wrapper. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The header file for the C++ class base_class.h and the classes themselves in base_class.cpp: &lt;br /&gt;
&amp;lt;pre&amp;gt;#ifndef _BASE_CLASS_H_&lt;br /&gt;
#define _BASE_CLASS_H_&lt;br /&gt;
&lt;br /&gt;
class base&lt;br /&gt;
{&lt;br /&gt;
   public:&lt;br /&gt;
      base(double x_in);&lt;br /&gt;
      virtual ~base(void);&lt;br /&gt;
      void set_x(double x_in);&lt;br /&gt;
      void get_x(double* x_out);&lt;br /&gt;
      void sqr_x(void);&lt;br /&gt;
&lt;br /&gt;
   private:&lt;br /&gt;
      double x;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* _BASE_CLASS_H_ */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The base_class.cpp (the classes) &lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;base_class.h&amp;quot;&lt;br /&gt;
#include &amp;amp;lt;windows.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
base::base(double x_in)&lt;br /&gt;
{&lt;br /&gt;
   x = x_in;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
base::~base ()&lt;br /&gt;
{&lt;br /&gt;
   /* clean up */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   void base::set_x(double x_in)&lt;br /&gt;
   {&lt;br /&gt;
     x = x_in;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
void base::get_x(double* x_out)&lt;br /&gt;
{&lt;br /&gt;
   *x_out = x;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void base::sqr_x(void)&lt;br /&gt;
{&lt;br /&gt;
   x*=x;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;The header file for the wrapper c_dll_wrapper.h &lt;br /&gt;
&amp;lt;pre&amp;gt;#ifndef _C_DLL_WRAPPER_H_&lt;br /&gt;
#define _C_DLL_WRAPPER_H_&lt;br /&gt;
&lt;br /&gt;
/* building a DLL */&lt;br /&gt;
#define DLLIMPORT __declspec (dllexport)&lt;br /&gt;
&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
   extern &amp;quot;C&amp;quot; { /* using a C++ compiler */&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
   typedef struct base base; /* make the class opaque to the wrapper */&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT base* create_base(double x_in);&lt;br /&gt;
   DLLIMPORT void set_x(base* LV_ref, double x_in);&lt;br /&gt;
   DLLIMPORT void get_x(base* LV_ref, double* x_out);&lt;br /&gt;
   DLLIMPORT void destroy_base(base* LV_ref);&lt;br /&gt;
   DLLIMPORT void sqr_x(base* LV_ref);&lt;br /&gt;
&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
   }&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#endif /* _C_DLL_WRAPPER_H_ */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the wrapper itself, c_dll_wrapper.cpp &lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;quot;c_dll_wrapper.h&amp;quot;&lt;br /&gt;
#include &amp;quot;base_class.h&amp;quot;&lt;br /&gt;
#include &amp;amp;lt;windows.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT base* create_base(double x_in)&lt;br /&gt;
   {&lt;br /&gt;
      return new base(x_in);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void set_x(base* LV_ref, double x_in)&lt;br /&gt;
   {&lt;br /&gt;
      LV_ref-&amp;amp;gt;set_x(x_in);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void get_x(base* LV_ref, double* x_out)&lt;br /&gt;
   {&lt;br /&gt;
      LV_ref-&amp;amp;gt;get_x(x_out);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void destroy_base(base* LV_ref)&lt;br /&gt;
   {&lt;br /&gt;
      delete LV_ref;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   DLLIMPORT void sqr_x(base* LV_ref)&lt;br /&gt;
   {&lt;br /&gt;
      LV_ref-&amp;amp;gt;sqr_x();&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,&lt;br /&gt;
                       DWORD reason /* Reason this function is being called. */ ,&lt;br /&gt;
                       LPVOID reserved /* Not used. */ )&lt;br /&gt;
{&lt;br /&gt;
   switch (reason)&lt;br /&gt;
   {&lt;br /&gt;
      case DLL_PROCESS_ATTACH:&lt;br /&gt;
         break;&lt;br /&gt;
      case DLL_PROCESS_DETACH:&lt;br /&gt;
         break;&lt;br /&gt;
       case DLL_THREAD_ATTACH:&lt;br /&gt;
         break;&lt;br /&gt;
      case DLL_THREAD_DETACH:&lt;br /&gt;
         break;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Returns TRUE on success, FALSE on failure */&lt;br /&gt;
   return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Bsvingen</name></author>
	</entry>
</feed>