Managed C++, Interop and FILETIME
At home I do a lot of interop with the Win32 API. Over time after I saw myself writing the same interop code on several different projects so I started working on a centralized library for this type of code. Originally I wrote this library in C#. It was the language I used the most at the time and my brief experience with MC++ in Everret was too painful to justify using it.
Recently I've started interoping with much more advanced structures. I found that I was spending a lot of my time redefining structures, enums and defines that I am just using as a middle layer for the purpose of interop. Tracking down the value for every enum is tedious and very time consuming. This lead me to re-evaluate my choice of C# for the langauge since I could avoid this pain if I was using MC++.
A quick aside here. I am aware of several projects that exist where people have written scripts that will convert C++/C header files into their C# equivalent. I avoid these for style reasons. I find defines such as NERR_Sucess, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT unintuive. When I write my interop layer I write enums that convert these into "more useable" types like so
public enum class LogonProvider
{
Default = LOGON32_PROVIDER_DEFAULT,
...
};
I was aware that MC++ had a lot of changes in Whidbey so I decided to try it out. I must say that the new syntax for MC++ is a vast improvement over the original. As a result I fully switched my interop library over to MC++. After the initial learning period (< 1 week) I now find that I write my interop code much faster. Most of the time saved revolves around not having to look up the values for #defines, enums and such. This lets me fully devote my time to writing elegant wrappers for the Win32 API.
Thus far I have only run into one issue that is caused a bit of grief. The namespace System::Runtime::InteropServices defines a structure FILETIME. Unfortunately, a similar structure is included in a lot of Windows header files (eg Lm.h). So if you include one of those header files and that namespace you will get a compile error. There does not seem to be an easy way around this.
The best solution that I have found to this point is to typedef out all of the classes that I need from the namespace in stdafx.h like so
typedef System::Runtime::InteropServices::Marshal Marshal;
typedef System::Runtime::InteropServices::COMException COMException;
Overall I found the switch to MC++ for interop purposes in Whidbey to be a real time saver and I would recomend it to devs who write a lot of interop layer code
Comments
- Anonymous
February 21, 2005
The comment has been removed - Anonymous
February 21, 2005
All you probably need to do is this:
using System::Runtime::InteropServices::Marshal;
and 'Marshal' will be available to you. - Anonymous
February 21, 2005
Vatsan, that is the problem that he was having - if he included that using statement and Lm.h, there were compile errors because FILETIME was redefined. However, using the typedef's that he listed above alows him to easily access those classes and avoid the compiler error. - Anonymous
February 28, 2005
There´s another "partial" solution to that, quote from msdn: "Solving Ambiguous References.
One way to overcome this problem is to include the unmanaged headers first, before any managed using declarations. In this order, the compiler can process the unmanaged headers first and the ambiguity does not occur unless the code uses one of the symbols."