<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Cluebat-man to the rescue : .NET</title><link>http://msmvps.com/blogs/vandooren/archive/tags/.NET/default.aspx</link><description>Tags: .NET</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Using reflection to ease code maintenance</title><link>http://msmvps.com/blogs/vandooren/archive/2008/12/02/using-reflection-to-ease-code-maintenance.aspx</link><pubDate>Tue, 02 Dec 2008 11:35:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1655548</guid><dc:creator>vanDooren</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1655548</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1655548</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/12/02/using-reflection-to-ease-code-maintenance.aspx#comments</comments><description>&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Currently I am programming an application for performing code analysis on the software that controls the production process. Apart from the parsing of the code, and iterating across a hierarchical representation of the expression tree, &lt;i style="mso-bidi-font-style:normal;"&gt;all&lt;/i&gt; these rules (verifications) have to be executed against all the code.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I could change the code verifier every time I implemented a new rule, but instead I used reflection to do this for me. Every verification that has to be done is represented by a class that implements the right interface. This interface defines the prototype of the method that performs the verification.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IActionVerification&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; Verify(&lt;span style="color:#2b91af;"&gt;CodeContext&lt;/span&gt; context);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The context variable contains the complete context of the portion of the code that is being looked at: the current action, step, function block and phase.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;When a new code verifier instance is create, it will use reflection to examine the current assembly, and extract all classes that implement this interface.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; CodeVerifier()&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;actionVerifications = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IActionVerification&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; currAssembly = &lt;span style="color:#2b91af;"&gt;Assembly&lt;/span&gt;.GetExecutingAssembly();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;foreach&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; t &lt;span style="color:blue;"&gt;in&lt;/span&gt; currAssembly.GetTypes())&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (&lt;span style="color:blue;"&gt;null&lt;/span&gt; != t.GetInterface(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;IActionVerification&lt;/span&gt;).Name))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;actionVerifications.Add(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;IActionVerification&lt;/span&gt;)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;currAssembly.CreateInstance(t.FullName));&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This way, it is very easy to populate the list of all verifications to do. The code verification itself is conceptually as simple as this:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;foreach&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; (&lt;span style="color:blue;"&gt;var&lt;/span&gt; verification &lt;span style="color:blue;"&gt;in&lt;/span&gt; actionVerifications)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;verification.Verify(context);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Implementing a new verification is the as easy as creating a new class and implementing the interface. After that everything will be done automatically. Ading a new verification is as easy as this:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ActionExpressionCount&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;IActionVerification&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;span style="color:gray;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Verify(&lt;span style="color:#2b91af;"&gt;CodeContext&lt;/span&gt; context)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (context.Action.ParsedExpression.Count &amp;lt; 1)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ActionExpressionCountInvalid&lt;/span&gt;.LogIssue(context);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Hip hip hooray for the .NET framework!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1655548" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Interoperability/default.aspx">Interoperability</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Extending a native C++ project with managed code</title><link>http://msmvps.com/blogs/vandooren/archive/2008/09/03/extending-a-native-c-project-with-managed-code.aspx</link><pubDate>Wed, 03 Sep 2008 09:59:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1646601</guid><dc:creator>vanDooren</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1646601</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1646601</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/09/03/extending-a-native-c-project-with-managed-code.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;One question that comes up from time to time in the newsgroups is &amp;lsquo;I have a native C++ project and I want to extend it with Managed code (e.g. Windows Forms). What do I do?&amp;rsquo;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;The answer is not so complex. It is fairly easy to extend native projects with managed code. In this article I&amp;rsquo;ll explain how.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:medium;color:#17365d;font-family:Calibri;"&gt;What NOT to do&lt;/span&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;To quote &lt;/span&gt;&lt;a href="http://www.gregcons.com/kateblog/"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Kate Gregory&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt; &amp;lsquo;In the name of all that is good and right: Do not set /CLR for the entire project&amp;rsquo;.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;/CLR tells the compiler that it should compile a source file as C++/CLI code in which it finds both native and managed C++ code. Theoretically you could specify this for the whole project, but this has some serious consequences.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Apart from the fact that it is possible for the compiled output size to explode, there can be significant problems with COM and CRT initialization. I am no interop expert in the matter like &lt;/span&gt;&lt;a href="http://www.heege.net/blog/default.aspx"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Marcus Heege&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt; or Kate, but I am willing to take their word for it.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Furthermore, your existing project is possibly validated by QA en unit tested 7 days from Sunday. You don&amp;rsquo;t want to travel that road again if you can prevent it.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:medium;color:#17365d;font-family:Calibri;"&gt;What to do&lt;/span&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;You want to add managed stuff to your project while impacting the rest of the code as little as humanly possible. To achieve this you have to compartmentalize the managed stuff and give it a native interface that you can use in the native parts of you projects without any hassle.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;I think I can best explain this with a practical example.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;For the sake of this example I have a native DLL project that exports a function that returns an integer value. Perhaps this function got that integer value previously through an MFC interface, and now that value has to come from a Windows Forms interface.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:small;color:#17365d;font-family:Calibri;"&gt;Add the windows form to your project&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;This is the first and also the easiest step of the process. Rightclick your project and select &amp;lsquo;Add&amp;hellip;-&amp;gt;New Item&amp;rsquo; and select &amp;lsquo;UI-&amp;gt;Windows Form&amp;rsquo; in the Visual C++ dialog.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;You will then get a message box, telling you that your project will be converted to a managed project. Here you click &amp;lsquo;yes&amp;rsquo;. Even though you don&amp;rsquo;t want to compile your project with /clr, Visual Studio itself needs to know that you are doing managed stuff in your project. This is not necessary for compiling your project, but if you want to have the benefit of working with the forms designer and other .NET related things, then it would be a good idea. And you cannot add the form if you choose &amp;lsquo;No&amp;rsquo; so it&amp;rsquo;s not like you have much choice anyway.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Now you have a .NET Windows Form in your code. You can verify the file specific settings if you want, but the cpp file will be compiled with the /clr flag set, and without the use of precompiled headers. Not using precompiled headers is important, because the default precompiled header is compiled without /clr set, and this would lead to conflicts.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Of course, if you need to, you can create a copy of StdAfx.h/cpp cpp files called &amp;lsquo;StdAfxClr.h/cpp&amp;rsquo; add them to your project, and configure them to create a managed precompiled header, which you could then use for all files that are compiled with /clr. This is not necessary for small projects, but it could be a useful optimization in large projects.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="color:#17365d;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;The interface layer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;At this point you can compile and link the entire project, but your native code isn&amp;rsquo;t yet using the new managed functionality. And because the native code will not be compiled with /clr, it will never do so. In order to make that happen, you will need a thin layer between the native and managed code. This layer will have a native C or C++ interface which can be called by the native code, and a managed implementation that will do all the .NET stuff.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;In our example, the interface is 1 simple C style function in Interface.h:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;int&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &lt;span style="color:blue;"&gt;__stdcall&lt;/span&gt; DoManagedStuff(&lt;span style="color:blue;"&gt;void&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;And this function has a simple implementation in Interface.cpp:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;int&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &lt;span style="color:blue;"&gt;__stdcall&lt;/span&gt; DoManagedStuff(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;DemoForm ^df = &lt;span style="color:blue;"&gt;gcnew&lt;/span&gt; DemoForm();&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;df-&amp;gt;ShowDialog();&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; df-&amp;gt;Value;&lt;br /&gt;}&lt;/span&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Interface.h and Interface.cpp are 2 new files that you have to add to your project. You have to manually configure the cpp file to be compiled with /clr, and to not use precompiled headers.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;As you can see, the interface layer provides a clean native interface for the managed stuff that you want your code to perform. Of course, you are not limited to C style interfaces. You can also work with classes and make classes with a native interface and a managed implementation. But there are a couple of issues that you need to be aware of. If you want to go there, then it would be a good idea to read &lt;/span&gt;&lt;a href="http://www.gotw.ca/publications/C++CLIRationale.pdf"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;the paper written by Herb Sutter&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt; which explains the rationale behind C++/CLI, as well as some of the limitations and pitfalls.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Actually, reading that paper is a good idea for anyone working with C++/CLI who also cares about understanding what is actually going on behind the scenes.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:small;color:#17365d;font-family:Calibri;"&gt;Using the interface layer&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;All the hard work is done. Now you can simply include Interface.h in your native code files, and call &amp;lsquo;DoManagedStuff&amp;rsquo; where appropriate.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#include&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &lt;span style="color:#a31515;"&gt;&amp;quot;stdafx.h&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;br /&gt;#include&lt;/span&gt; &lt;span style="color:#a31515;"&gt;&amp;quot;InterfaceLayer.h&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; &lt;span style="color:blue;"&gt;__stdcall&lt;/span&gt; DoFoo(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; DoManagedStuff();&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:10pt 0cm 0pt;"&gt;&lt;span style="font-size:small;color:#17365d;font-family:Calibri;"&gt;Conclusion&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;As you can see, extending native code with managed code is not so hard. At least, it isn&amp;rsquo;t if you maintain a clean break between managed and native code. If you cannot do this, things might become more difficult. For example, using .NET controls on an MFC dialog, or using .NET remoting in a native COM project are things that can be much more tricky.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;Another thing you should be aware of is that not all compiler switches can be used in conjunction with the /clr&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;switch. The compiler will inform you if it detects this. The combinations which are not allowed are documented, and can be found in the documentation of the /clr switch itself.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;This post was not meant to be an exhaustive how-to to those complex scenarios, but instead an explanation behind the basic ideas.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Calibri;"&gt;The demo project for this article can be downloaded under the MIT license as usual. &lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1646601" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.64.66.01/DemoDll.zip" length="18800" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Interoperability/default.aspx">Interoperability</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Excel and OleDb stupidity</title><link>http://msmvps.com/blogs/vandooren/archive/2008/02/29/excel-and-oledb-stupidity.aspx</link><pubDate>Fri, 29 Feb 2008 20:47:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1528706</guid><dc:creator>vanDooren</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1528706</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1528706</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/02/29/excel-and-oledb-stupidity.aspx#comments</comments><description>&lt;p&gt;This afternoon I was working on a Windows Forms app for the finance guys, to help them allocate costs to systems, proportional to predefined allocation keys.&lt;/p&gt;
&lt;p&gt;The app has to import Excel spreadsheet files and perform all the database actions.&lt;/p&gt;
&lt;p&gt;The key columns to uniquely identify a cost are text values. Unfortunately, some of those key values do not contain letters, but only numeric characters. And this is where it sucks to have to work with Excel.&lt;/p&gt;
&lt;p&gt;This is because Excel knows no datatypes. You can specify formatting for cells, but Excel ignores that when someone asks for cell data. Instead, it scans the first couple of rows to guess the datatype. By default it checks the first 8 rows. If those contains mixed values, it uses a specified default type for those values that are not numeric.&lt;/p&gt;
&lt;p&gt;This means that if you use OleDb to retrieve values, the column type can vary per row.&lt;/p&gt;
&lt;p&gt;What can you do about it? Well nothing really. You can tweak some values, and hope that you will never encounter the corner cases that you cannot do anything about. There is plenty of information to be found. One good explanation was &lt;a class="" href="http://www.brianpeek.com/blog/archive/2006/04/18/415.aspx"&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, one of the finance guys gave me an incredibly useful tip, which you can use as a workaround. You have to manually make a couple of easy modifications to the excel file, and Excel will always use the text data type.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div&gt;Assume that the offending data is in column 1, and that the first row is the header row.&amp;nbsp;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;You insert 2 empty columns to the right of the offending column.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Put an &amp;#39; in the first cell of the first empty column (B2).&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Then enter =B2&amp;amp;B1in the cell B3.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Select B2 and B3, and double-click the bottom right corner of the selection box. This will copy the data from there to the last row.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;B3 will now hold the data as text, because the &amp;#39; tells Excel that no matter what is in the cell, it is text.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Then you copy column 3, paste it as &amp;#39;values only&amp;#39; over column 1.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Delete columns 2 and 3 again.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Now you can read the column in OleDb and always get text values for that column.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1528706" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Interoperability/default.aspx">Interoperability</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Excel/default.aspx">Excel</category></item><item><title>LINQ To SQL......Server 2005</title><link>http://msmvps.com/blogs/vandooren/archive/2007/12/05/linq-to-sql-server-2005.aspx</link><pubDate>Wed, 05 Dec 2007 12:06:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1380338</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1380338</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1380338</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2007/12/05/linq-to-sql-server-2005.aspx#comments</comments><description>&lt;p&gt;I am programming a small application for our finance department, for which I wanted to use LINQ for performing the data access, using Visual Studio 2008 Professional.&lt;/p&gt;
&lt;p&gt;Unfortunately -and no thanks to MSDN- I found out that currently there is only support for SQL Server 200x, and preferably SQL server 2005, and not every version of SQL Server 2005 at that.&lt;/p&gt;
&lt;p&gt;Finance uses MS Access 2003. They already use the database, and it has some exotic connection to MFGPro, involving terminal windows and an FTP connection. So I am not going to move their stuff over to SQL Server 2005 at the moment because the app and the database have to work by the end of the year.&lt;/p&gt;
&lt;p&gt;I really think this should have been documented properly. It seems that Microsoft&amp;nbsp;does not want to outright say that they dropped&amp;nbsp;Access from the supported databases list for LINQ. You can&amp;#39;t even find a &amp;#39;supported databases&amp;#39; list on the LINQ home page. According to a forum post by a Microsoft Employee, dropping Access was not a technical problem, but a matter of scheduling and other external factors. Yaaay.&lt;/p&gt;
&lt;p&gt;But for now&amp;nbsp;it might as well be named&amp;nbsp;&amp;#39;LINQ To SQL Server 2005&amp;#39;. I am curious if they will add support for Access later on. I wouldn&amp;#39;t hold my breath though.&lt;/p&gt;
&lt;p&gt;Back to ADO.NET for now, I guess.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1380338" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/.NET/default.aspx">.NET</category></item><item><title>I stand corrected: not all C++ programmers hate VB</title><link>http://msmvps.com/blogs/vandooren/archive/2007/07/01/i-stand-corrected-not-all-c-programmers-hate-vb.aspx</link><pubDate>Sun, 01 Jul 2007 21:02:02 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:996600</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=996600</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=996600</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2007/07/01/i-stand-corrected-not-all-c-programmers-hate-vb.aspx#comments</comments><description>&lt;p&gt;As I already mentioned before, it&amp;#39;s a small world after all. (Hearing that annoying Disney tune yet in your head &lt;span style="font-family:Wingdings;"&gt;J&lt;/span&gt;).
&lt;/p&gt;&lt;p&gt;I am writing an article about C++/CLI in which I use a quote from my fellow VC++ MVP Kate Gregory. I did a quick search to find her blog in order to link it to her name in the article. I read a couple of blog posts and to my surprise I &lt;a href="http://www.gregcons.com/KateBlog/MoreOnLanguagePreferences.aspx"&gt;found one&lt;/a&gt; in which she mentioned a blog post I wrote earlier in which I talked about &lt;a href="http://msmvps.com/blogs/vandooren/archive/2007/02/05/is-c-still-a-viable-language.aspx"&gt;the viability of C++&lt;/a&gt; in this day and age.
&lt;/p&gt;&lt;p&gt;In my blog post I mention that I think VB is ugly and that most people in the C++ forums would agree with me.
&lt;/p&gt;&lt;p&gt;Apparently there is at least 1 VC++ MVP (Kate) who likes VB. That is at least 1 very skilled and well respected C++ programmer who likes VB. 
&lt;/p&gt;&lt;p&gt;So I hereby concede that VB is a full fledged member of the .NET programming world, and that there are even C++ programmers who like it. &lt;span style="font-size:6pt;"&gt;Just as long as I don&amp;#39;t have to like it.&lt;/span&gt;
	&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=996600" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Executing LabVIEW VIs through C style function pointers via .NET</title><link>http://msmvps.com/blogs/vandooren/archive/2006/11/16/executing-labview-vis-through-c-style-function-pointers-via-net.aspx</link><pubDate>Thu, 16 Nov 2006 11:46:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:294594</guid><dc:creator>vanDooren</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=294594</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=294594</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2006/11/16/executing-labview-vis-through-c-style-function-pointers-via-net.aspx#comments</comments><description>&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Problems exist to be solved.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Some problems are so complex that you cannot solve them when you need to. With other problems it is not a matter of complexity, but a matter of not having all the pieces of the puzzle.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Some problems are so interesting that it pays to keep them in the back of your head, just in case you ever find that missing piece that allows you to solve them.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;One of those problems is that with the current LabVIEW external library interface it is impossible to execute LabVIEW VIs in a DLL through a C style function pointer.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;This feature does not exist, even though lots of programmers would really benefit from it.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;2 weeks ago I was active on the Visual C++ newsgroup as usual, when learned –by pure coincidence- about an advanced function in the .NET framework called Marshal.GetFunctionPointerForDelegate.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;I immediately realized that this was the key to solving the old C style function pointer issue&lt;/FONT&gt;&lt;/P&gt;
&lt;H2 style="MARGIN:12pt 0in 3pt;"&gt;&lt;EM&gt;Problem description&lt;/EM&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Suppose that we have a DLL that exports a function. This function takes a function pointer as an argument, to be executed sometime later to pass some data to the calling application.&lt;/FONT&gt;&lt;/P&gt;
&lt;H3 style="MARGIN:12pt 0in 3pt;"&gt;The Test DLL code&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The idea is to test the ability to run a LabVIEW VI through a function pointer. To test this we need a DLL which will test this for us.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The following very simple test function has been created for this purpose.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;This is the expected prototype of the callback function&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;typedef&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; (&lt;SPAN style="COLOR:blue;"&gt;__stdcall&lt;/SPAN&gt; *fSimpleCallBack)(&lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; i);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;And this is the DLL function that will perform our test:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';"&gt;//Test of the simple callback&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;void&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; Simplefoo(&lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; i, fSimpleCallBack cb)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;(cb)(i);&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//invoke the callback function.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;As you can see, the LabVIEW VI will be executed with the supplied parameter through the supplied function pointer.&lt;/FONT&gt;&lt;/P&gt;
&lt;H2 style="MARGIN:12pt 0in 3pt;"&gt;&lt;EM&gt;Principal solution&lt;/EM&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The very first action has to be creating a .NET delegate of which the signature matches the signature of the CallBack function that is required.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Then a proxy class is created with only 2 members: an event that is based on the new delegate function, and a method called ‘GetDelegate’.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;LabVIEW has the ability to link a LabVIEW VI with a .NET event. The VI prototype is generated automatically, and matches the event delegate signature.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;After registering a VI for the specified event, LabVIEW uses the GetDelegate method of our proxy class to extract the registered delegate from the event. That delegate is then converted to a function pointer via the ‘GetFunctionPointerForDelegate’ method of the Marshal class.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;That function pointer can then be supplied to a native function that can execute the LabVIEW VI directly through the function pointer without requiring any modification at all.&lt;/FONT&gt;&lt;/P&gt;
&lt;H3 style="MARGIN:12pt 0in 3pt;"&gt;A note on GetFunctionPointerForDelegate&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The documentation for this method is sparse. It seems that VS2005 and .NET2.0 were rushed out of the door without taking the time to fully document the more advanced functions and providing code samples in the documentation.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Because of this, it is easy to miss that GetFunctionPointerForDelegate returns a pointer that uses the __stdcall calling convention by default.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;It is also easy to overlook the fact that you can change this.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;If you need a function pointer that uses another calling convention - e.g. __cdecl – then you can achieve this by applying the UnmanagedFunctionPointerAttribute attribute to the delegate definition.&lt;/FONT&gt;&lt;/P&gt;
&lt;H3 style="MARGIN:12pt 0in 3pt;"&gt;The .NET code&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;namespace&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; FunctionPointerProxy&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;SimpleProxy&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//Marshal a simple integer parameter as 32 bit integer.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;delegate&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;SimpleProxyDelegate&lt;/SPAN&gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;[&lt;SPAN style="COLOR:teal;"&gt;MarshalAs&lt;/SPAN&gt;(&lt;SPAN style="COLOR:teal;"&gt;UnmanagedType&lt;/SPAN&gt;.I4)] &lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; i);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//export an event because that is the only way we are going to get&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//LabVIEW to give use a delegate.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;event&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;SimpleProxyDelegate&lt;/SPAN&gt; SimpleEvent;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//extract the delegate from the event. If there was no event&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//registered, this will trigger an exception which is caught by the&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//LabVIEW .NET interface node. No need to worry about it here.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;Delegate&lt;/SPAN&gt; GetDelegate()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; SimpleEvent.GetInvocationList()[0];&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;This is all the additional code you really need to make it work. The delegate function has to mirror the native callback prototype for 100%. To achieve this you have to use the MarshalAs attribute on each delegate parameter to insure correct behavior.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The event simply has to exist because LabVIEW has only 1 way to produce a delegate for a VI, and that is by registering a VI to an event.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;And even then, the delegate is never directly accessible, so we have to create a ‘GetDelegate’ method that extracts the registered delegate, and returns it to LabVIEW.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;As far as the .NET framework is concerned, we could simply make the event and the GetDelegate method static to remove the need to instantiate an object that we won’t need for anything else. But there are 2 reasons why we don’t do that:&lt;/FONT&gt;&lt;/P&gt;
&lt;UL style="MARGIN-TOP:0in;"&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l1 level1 lfo3;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;LabVIEW does not support registering VIs to static events.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l1 level1 lfo3;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Our GetDelegate function would need way to know which delegate you want to get, in case there are multiple instances of callback VIs. Since the event is tied to an instance, it is easy enough to keep track of the events in LabVIEW.&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;H3 style="MARGIN:12pt 0in 3pt;"&gt;The LabVIEW code&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;LabVIEW code is graphical, so I have chosen to mark the different steps in the block diagram below, and then add an explanation of each step in a numbered list.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;&lt;IMG style="WIDTH:963px;HEIGHT:341px;" height=341 src="http://www.bdvd.be/images/blog_lvcallback1/1_principle.jpg" width=963&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;OL style="MARGIN-TOP:0in;"&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l2 level1 lfo5;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Instantiate a new SimpleProxy Class. We only need it to access the event. Sadly, LabVIEW does not yet support static events.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l2 level1 lfo5;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Register a VI for the Event. The way to do this is to wire the SimpleProxy refnum to the event source and select the appropriate event. Right-click 'VI Ref' and select 'Create Callback VI'. This will automatically generate a VI with the correct input and output parameters for you. This will also automatically wire a static VI reference to the VI Ref input. User parameter can be any LabVIEW type at all that you want to pass to the VI when the .NET event is triggered. We don't need it, but if we did we would have to wire it before we generate the callback VI because it changes the VI prototype.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l2 level1 lfo5;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Now that the event is registered, we can simply get the .NET delegate that represents the VI callback out of it.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l2 level1 lfo5;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Use a static member of the Marshal class to get a funtion pointer to the delegate. This is where the magic happens. A native stub is generated for the delegate at runtime. The unmanaged parameter list is built according to the Marshalling attributes that were attached to the delegate signature.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l2 level1 lfo5;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Cast the Delegate IntPtr to an Int32. Pointers are 32 bit on the x386 platform. We need this 32 bit value to supply it to the DLL function call that expects a 32 bit function pointer. Note that this function pointer uses the standard calling convention by default (see below for more info).&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l2 level1 lfo5;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;We no longer need the FunctionPointer IntPtr. As long as the delegate itself is still in memory, the native stub will be valid.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l2 level1 lfo5;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Execute the DLL function. This function will use the supplied callback function pointer to execute the callback VI. It will pass the supplied int parameter to the callback vi at the time of the function call.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l2 level1 lfo5;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Unregister the Callback VI from the event, and close the various references that were opened.&lt;/FONT&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;H3 style="MARGIN:12pt 0in 3pt;"&gt;Running the test&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;As is sometimes said: the proof is in the pudding.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;To verify that everything works as advertised, I have put a simple dialog box in the callback VI that displays the value of the integer parameter.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Simply run the example and you will see the following dialog box:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;IMG style="WIDTH:214px;HEIGHT:104px;" height=104 src="http://www.bdvd.be/images/blog_lvcallback1/2_result.jpg" width=214&gt;&lt;/P&gt;
&lt;H2 style="MARGIN:12pt 0in 3pt;"&gt;&lt;EM&gt;Advanced implementation&lt;/EM&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The principal solution works, but is not yet ideal. Most importantly, there is too much clutter on the LabVIEW diagram for this solution to be aesthetically pleasing.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;There are too many manual actions that have to be repeated each time you implement a callback function. I also wanted to show you an example of a callback function that is a bit more complex.&lt;/FONT&gt;&lt;/P&gt;
&lt;H3 style="MARGIN:12pt 0in 3pt;"&gt;Test DLL&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Consider the following callback prototype that is a bit more complex than the previous one:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;typedef&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; (&lt;SPAN style="COLOR:blue;"&gt;__stdcall&lt;/SPAN&gt; *fAdvancedCallBack)(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; i,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;char&lt;/SPAN&gt;* aString,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;wchar_t&lt;/SPAN&gt;* wString);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Here we need to supply an integer, an ASCII string and a UNICODE string. The function exported from the DLL has the following implementation:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;void&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; Advancedfoo(&lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; i, &lt;SPAN style="COLOR:blue;"&gt;char&lt;/SPAN&gt;* aString, fAdvancedCallBack cb)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;BSTR uString;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; aLength = lstrlenA(aString);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; uLength = ::MultiByteToWideChar(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;CP_ACP, 0, aString, aLength, 0, 0);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt;(0 &amp;lt; uLength)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;uString = SysAllocStringByteLen(0, uLength);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;::MultiByteToWideChar(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;CP_ACP, 0, aString, aLength, uString, uLength);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;else&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;uString = L&lt;SPAN style="COLOR:maroon;"&gt;""&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//invoke the callback function through its function pointer.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;(cb)(i, aString, uString);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;LabVIEW itself does not support UNICODE strings, so we manually transform the supplied ASCII string to UNICODE. Apart from that the function body only contains a function call via the supplied callback pointer.&lt;/FONT&gt;&lt;/P&gt;
&lt;H3 style="MARGIN:12pt 0in 3pt;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;.NET code&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;[&lt;SPAN style="COLOR:teal;"&gt;UnmanagedFunctionPointerAttribute&lt;/SPAN&gt;(&lt;SPAN style="COLOR:teal;"&gt;CallingConvention&lt;/SPAN&gt;.Cdecl)]&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;AdvancedProxy&lt;/SPAN&gt; : &lt;SPAN style="COLOR:teal;"&gt;IProxy&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;delegate&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;AdvancedProxyDelegate&lt;/SPAN&gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//A simple I4 parameter. Nothing special&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;[&lt;SPAN style="COLOR:teal;"&gt;MarshalAs&lt;/SPAN&gt;(&lt;SPAN style="COLOR:teal;"&gt;UnmanagedType&lt;/SPAN&gt;.I4)] &lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; i,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//An ASCII string. this will be marshalled as UNICODE on the&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//.NET side and ASCII on the unmanaged side.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;[&lt;SPAN style="COLOR:teal;"&gt;MarshalAs&lt;/SPAN&gt;(&lt;SPAN style="COLOR:teal;"&gt;UnmanagedType&lt;/SPAN&gt;.LPStr)] &lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; aString,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//A UNICODE string. This will be marshalled as UNICODE on the&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//.NET side, and UNICODE on the unmanaged side.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;[&lt;SPAN style="COLOR:teal;"&gt;MarshalAs&lt;/SPAN&gt;(&lt;SPAN style="COLOR:teal;"&gt;UnmanagedType&lt;/SPAN&gt;.LPWStr)] &lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; wString);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;event&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;AdvancedProxyDelegate&lt;/SPAN&gt; AdvancedEvent;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;Delegate&lt;/SPAN&gt; GetDelegate()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; AdvancedEvent.GetInvocationList()[0];&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The meaning of the different parts is the same as with the SimpleProxy example. The only real difference – apart from the delegate signature of course – is that all classes that are used as a proxy between a LabVIEW VI and a function pointer should implement the interface IProxy.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;This interface has the following definition:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;public&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:blue;"&gt;interface&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;IProxy&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;Delegate&lt;/SPAN&gt; GetDelegate();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;This allows us to make the LabVIEW code for getting a function pointer generic, instead of tied to the type of the callback delegate.&lt;/FONT&gt;&lt;/P&gt;
&lt;H3 style="MARGIN:12pt 0in 3pt;"&gt;LabVIEW code&lt;/H3&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;IMG style="WIDTH:589px;HEIGHT:205px;" height=205 src="http://www.bdvd.be/images/blog_lvcallback1/3_advanced.gif" width=589&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;As you can see, the LabVIEW code is vastly simplified.&lt;/FONT&gt;&lt;/P&gt;
&lt;OL style="MARGIN-TOP:0in;"&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l5 level1 lfo6;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The only thing that we cannot make generic is the event registration, because the event and as a result the VI reference are strongly typed.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l5 level1 lfo6;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The process of retrieving the function pointer is generic because all proxy classes now implement the IProxy class for retrieving the event delegate.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l5 level1 lfo6;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The call to the test function in the DLL now also takes a string parameter that gets expanded to UNICODE inside the test function to supply the callback function with the correct parameters.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI class=MsoNormal style="MARGIN:0in 0in 6pt;mso-list:l5 level1 lfo6;tab-stops:list .5in;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Cleanup of the event and references is also generic.&lt;/FONT&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;There are 2 new VIs. These are generic, so you can reuse them without limitation. This also makes it easy to support an asynchronous callback mechanism. You can register the event and supply the function pointer to the DLL.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The DLL stores it inside, and uses it any time it needs to. Meanwhile, your LabVIEW program can continue processing. You can keep the references cluster around – for example in a buffer – until such time as you want to disable the callback mechanism again.&lt;/FONT&gt;&lt;/P&gt;
&lt;H2 style="MARGIN:12pt 0in 3pt;"&gt;&lt;EM&gt;Running the demo code&lt;/EM&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The Visual studio solution is for VS2005, and can be built with all versions of VS2005.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;The LabVIEW project uses version 8.2. You need at least version 8.0 to have decent .NET support, and I used 8.2 because that is the latest version at this moment.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;To run the demo, simply extract the sources and open and build the Visual studio solution. Then open the LV project and run the sample of your liking.&lt;/FONT&gt;&lt;/P&gt;
&lt;H2 style="MARGIN:12pt 0in 3pt;"&gt;&lt;EM&gt;Conclusion&lt;/EM&gt;&lt;/H2&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;This article has outlined a relatively simple way to directly execute a LabVIEW VI through a C style function pointer without having to write C or C++ code. The demo code for this article is available under the MIT license as usual.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;You still need to provide a .NET class library, but the code involved is so minimal and trivial that it should not stop anyone.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;This approach also makes it possible to use the wealth of win32 API functions that require a callback function without having to resort to writing C or C++ code.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;In the time it took me to write this article (which took longer than writing the code, as usual) I found 3 other ways to achieve the same result.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;One is an ugly kludge that only fakes the callback functionality. The other performs a true callback to a LabVIEW VI, but it is even uglier. The third one is fairly elegant but has some other limiting factors.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;I will explain those 3 lesser solutions in another article. Despite the fact that only one of them is useful; the principle behind all 3 of them might be of use in another situation.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;Finally, the whole LabVIEW and function pointer issue has existed for a long time among LabVIEW programmers. I have done a bit of research, and as far as I can tell, I am the first to ever solve this problem without requiring C or C++ code.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;So here and now I claim to be the first to implement and publicize a working C style function pointer callback mechanism in LabVIEW!&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 6pt;"&gt;&lt;FONT face="Times New Roman" size=3&gt;In my next article I will follow up with an example involving structures (Clusters in LabVIEW) and n dimensional arrays.&lt;/FONT&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=294594" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.29.45.94/LvFunctionPointerProxy1.zip" length="86568" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Interoperability/default.aspx">Interoperability</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/LabVIEW/default.aspx">LabVIEW</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/.NET/default.aspx">.NET</category></item></channel></rss>