A Trip Down Memory Lane

Some thoughts related to recent poking around with native code and living in a C++ and COM world. It sure is great to get to use managed code most of the time!

Last week and this week, I’ve been busy writing native code in C++... something I haven’t done regularly since switching to managed code programming almost 6 years ago. Recently I found myself needing to implement some funky custom logic for picking a CLR version to run my component against, and the only solution that came up was to write native code with calls to things like CorBindToRuntimeEx.

I have to admit, I didn’t exactly look forward to it. For sometime now, my interaction with native code has been limited to defining and using COM-interop wrappers and P/invoke declarations. Coding directly in native code brought back small nuisances like having separate header files, as well as more stark differences in programming patterns such as calling an API with NULL first to get the required size of the buffer that needs to be allocated, allocating the buffer, and then calling the API once again to actually get the data. Some more things that came back were the HRESULTs and BOOLs, the ???Ex methods, inconsistencies in how the different APIs work, and the need to look at MSDN every so often. But it paid to have had past experience with C++, COM and Win32, and memory management... it all seems to come back when needed. Of course, in the end, this just serves as a reminder of how much more productive managed code really is, and to be thankful I get to use it most of the time. This might sound weird [now], but the irony is that about the time I switched, I preferred native code programming, and was on the fence with the whole "managed code thing!" Times sure have changed...

For the curious, my goals were to create a managed COM object and an NT service that always ran against the latest version of the CLR present on the machine. For the first, the approach I took was to implement the minimal logic in native code (just the IClassFactory implementation, which acted as a shim to load in the right version of the CLR, and then create the managed object in its CreateInstance implementation) while keeping the majority of the logic in managed code. For the second, I had to do more and implement most of the NT service in native code. Both worked like a charm!

Posted on Friday, 1/14/2005 @ 12:47 PM | #Projects


Comments

3 comments have been posted.

Dan McKinley

Posted on 1/15/2005 @ 6:24 AM
Any chance of seeing some example code, or is this a proprietary thing? As it turns out I mind end up needing to do pretty much the same thing in the near future.

Nikhil Kothari

Posted on 1/15/2005 @ 5:34 PM
This is something I was doing while working on IIS7, so I can't just post the code. But I can probably describe the general idea:

1. During startup, call CorBindToRuntimeEx passing in NULL for the version. This loads the latest version of the CLR. You also get back an ICorRuntimeHost reference. You can call GetCORVersion to get version information for the CLR loaded.
2. You can now use ICorRuntimeHost to get the default AppDomain, and create managed objects in that AppDomain. Or you can (as I did), simply call ClrCreateManagedInstance to create a managed type implementing a COM interface.

Thats pretty much it... my managed object contains the guts of the logic needed in my scenario. My native shim pretty much just loads things up. The NT service does the same but also has other code and is a bit more complex. MSDN and Google searches bring back decent samples for implementing basic NT services.

Dan McKinley

Posted on 1/17/2005 @ 10:19 AM
Much appreciated - thanks
The discussion on this post has been closed. Please use my contact form to provide comments.