Ok, so I really was chomping at the bit to blog.  Now that we've gone beta I can get a lot of things off of my chest.  Just too awkward to blog much before the product was announced, you know?  In this post I'm going to give a bit of info on how to write a managed dll that interops with unmanaged code.  (FYI: I can't really give the explicit details on how to access the Acrylic automation interfaces at this point.

This is going to be in Managed C++ in 2005.  I've mentioned before that it blows P/Invoking out of the water.  The syntax is radically different than the Managed Extensions for C++ that was in VS.Net and is really remarkably easy to read and use for those who know C#, so be strong! ;)

Making a project managed in C++ is simply a matter of setting the /clr switch, which you can get to in the project properties panel under "Configuration Properties: General: Project Defaults: Common Language Runtime support".  There are some variations of this switch that are pretty well documented and I won't go into them here.  Our configuration type is "Dynamic Library (.dll)", of course.  (This is in the same properties area.)

We include the standard <windows.h> header and windows version pound defines as we need access to the Win32 api in a number of places.  Here's a simplified code snippet that shows you how things work:

// Plugin.h
// You need to include the relevant headers for the interfaces you're trying to hit. // This would be defined by the App you're trying to interact with. #include "AppPlugginInterfaceHeaders.h"
extern "C" // Or "C++" whatever your application uses {    //    // The application plugin entry point.    // The __declspec(dllexport) specifies that this function should be exported.    // IApplicationPluginHost is defined in the header provided by the app and included above.    //    __declspec(dllexport) bool PluginEntry(IApplicationPluginHost *hostAPIs); }  
// Plugin.cpp

// Or wherever else you have your windows includes if you do.. #include "Stdafx.h" #include "Plugin.h"
__declspec(dllexport) bool PluginEntry(IApplicationPluginHost *hostAPIs) {    // Code to check and save the interface passed back from the application. }

That's pretty much the sum of it.  From there it's using the host api pointer to grab other interfaces and access functions through those interfaces.  So something like hostAPIs->SomeFunction(). We do also have a DllMain (which must be unmanaged according to the SDK) to do some thread initialization that is very app specific in our case.  (This would be DLL_THREAD_ATTACH and DLL_THREAD_DETACH message processing.)

In case you're curious, putting completely unmanaged code in your /clr app requires a #pragma managed(push, off) statement before said code and a #pragma managed(pop) afterwords.