In the C++ world, many DLLs offer a static .lib that simplifies the use of the DLL - you just link in the .lib and you don't need to mess with all the
GetProcAddress stuff. The managed equivalent is accomplished - very simply - by adding a reference. And, of course, unmanaged DLLs' functionality can be imported on a function-by-function basis via the
DllImport attribute. However, I was curious to see if it were possible to use a C .lib in the C# world; it is, and this article demonstrates how to do it. I used Port95NT for my demo, but of course you can do this for any unmanaged .lib. Certainly, some readers will immediately point out that using the .lib isn't necessary, that the
DllImport attribute does this for you and with a lot less complexity. And they're correct, of course, but I was simply curious to explore the use of a static .lib in the managed world and couldn't gauge the relative complexity without having done it.
I've been using Port95NT's DlPortIO.dll to read/write bits to my parallel port for many years with C++ by using the associated DlPortIO.lib and a custom wrapper class. Since I've moved to (mostly) C#, I wanted to create a managed assembly to standardize the interface to DlPortIO.dll. I started by using the
DllImport attribute, then for kicks took a left turn into exploring the use of the .lib that comes with the DLL.
Using the Code
The attached Zip contains two VS2008 projects:
- A managed C++ wrapper DLL (
DlPortIOWrapper) that presents the unmanaged .lib's functions as managed methods.
- A C# console app that demos the use of the wrapper DLL.
DlPortIOWrapper is brought into any managed project by simply adding a reference to it.
DlPortIOWrapper exposes a few managed C++ classes containing static methods, and their use is pretty simple. I learned the technique from approach #3 in http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/299da822-5539-4e5b-9ba7-b614e564c9f4/.
public ref class U8
static UCHAR Read(ULONG port)
Pretty straightforward stuff. Your C# code then simply calls:
Again, nothing special there. However, I was intrigued by the use of the
ref keyword in the C++ class - I had never seen it before (caveat: I haven't done much managed C++... I jumped directly from unmanaged C++ to C#). You can learn about
ref here: http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/d7d50e52-d30b-45eb-bfb2-a22dfe98b9e8.
Points of Interest
As mentioned, this was really just an exercise in figuring out if and how one uses a static .lib in the managed world. In the end, it wasn't really all that useful in my project because it would be simpler to just use the
DllImport attribute to pull the functions directly from the DLL. But I thought that someone might have a more useful need for using a .lib, so I wrote this up with the hope that someone might find it useful or at least interesting.
If you have a need for controlling hardware via the parallel port, Port95NT continues to be a useful tool. Visual Studio is a really great "control" environment for developing firmware via the parallel port... it's really nice to have a super-powerful IDE (e.g.: Edit & Continue) when the other end of the wire is controlled by an ICE (they're never friendly). Though Port95NT was originally created to solve WinNT's hardware abstraction and has "been out of print" for over a decade, copies of it have been cached all over the Web and it remains easy to find. Installation on WinXP is straightforward, but installation on Win7 requires an interesting trick to make it install properly - see http://weblog.hansotten.com/?p=914 for details. Full details, plus a downloadable Port95NT installer, plus the sample code attached here can be found at my Port95NT page: http://www.dlwrr.com/electronics/tools/Port95NT/.