Black Locust Software

Technology Solutions for Business

A C++/VB Programmer's .NET Odyssey



Background

I write this to document my own journey up the .NET learning curve and help other developers in similar circumstances. I was trained as a software developer, largely using C++. I came to love the down-and-dirty tricks of the language, the arcane but powerful little things. scanf, nested ternaries, and i += j++ all pleased me greatly.

But I have been working for the last 3 1/2 years in Visual Basic 6, so my C++ is a bit rusty. Now I am migrating certain pieces of a VB6 app to .NET -- Visual C++ .NET, that is. I'm back in the language I love, and I'm having a blast. My boss thinks I'm a little crazy, but that's OK.

To give you a little taste of what I'm doing, I'll say all I can about it. The project should be on the market in a couple months, but until then I can't specify too much. We are lifting one VB6 module from EmbTrak and reworking it so it can be used several different ways. EmbTrak will still use the whole thing, but we will provide a web service that uses this module. Also, TaylorMade-Adidas Golf is licensing a subset of it for an internal project. Full OO support and flexibility makes using the same modules in several different projects easy. That's one more reason I love C++!


Introducing .NET

Besides C++ review, there's a lot of .NET stuff to learn. I started with Teach Yourself Visual C++.Net in 24 Hours. Richard Simon & Mark Schmidt do the best job I have seen in covering the breadth of VC++ .NET's capabilities without lingering too long on one aspect.
  • .NET Framework is a virtual machine running the managed code. It provides extra memory protection & more sophisticated management, most notably garbage collection.
  • VC++ is the only .NET language that crosses the .NET boundary by allowing you to write both managed & unmanaged code.
  • Provides .NET-safe data types (page 43)
  • Provides a pretty cool String class
  • Provides a pretty crumby Array class that doesn't overload the [] operator. The one I wrote as a sophomore did that. Of course it tended to crash a lot too ...
  • Adds a __finally block to try..catch
  • A class or struct is managed if declared with __gc preceding it

Filling in the gaps and getting code samples

As any book will, Teach Yourself Visual C++ .NET in 24 Hours left some gaps in my understanding. Microsoft's Visual C++ .NET Reference was one of my first resources. It's got a lot of good information, but I've enjoyed the code samples for Kate Gregory's soon-to-be-published Visual C++ .Net Kick Start.

I did find that her examples were for the 2003 version of the product, not the 2002 that I had purchased several months ago. In order to load her examples, I had to edit the .vcproj files and change the edition to 7.0 from 7.10. Otherwise, all the examples I have tried so far have worked fine. I hope to read the book pretty soon.

Graphics & Image handling

This is one of the key attractions Visual C++ .NET has for me right now. GDI+ offers new stuff to make advanced graphics easier. Gradients, paths, certain curves - all are now supported, whereas GDI did not support them.
What I am enjoying is drawing to an Image object in memory, not to a device context. Once the Image is drawn, I can display it on the screen or printer or save it to a file. And I'm no longer limited to a BMP file. Several file types are now supported including JPEG, PNG, and GIF. We used to use a third party utility to create JPEGs. Now we use one line of code: I->Save(sDestName, System::Drawing::Imaging::ImageFormat::Jpeg);

File handling


I thought this was the same as before. fopen, fseek, etc. ... ah, life is still good! But ... those functions will not accept managed variables as parameters. _wfopen, for example, wants a filename of type const wchar_t*, and will not accept the __wchar_t __gc[] that the String class's ToCharArray provides.

ATL has file handling classes. To open a file, they call CreateFile which doesn't accept managed variables either.

Just when I was tempted to derive my own version of the String class and add a method that would provide a raw character array, Visual C++ .NET: A Primer for C++ Developers pointed me toward the File and FileStream classes. One lesson here is that .NET provides a class for everything. There's no reason to do things the hard way.

The File object does some basic work like moving, copying and deleting files. It also opens text files, creating a pointer to a StreamReader or StreamWriter object. Access to binary files, like I need for this project, requires the FileStream, BinaryReader, and BinaryWriter objects.

Here are more notes on the Reading and Seeking with the FileStream class.

Error and exception handling

The old if (f = _wfopen(sFileName,"r")) == NULL is now considered a poor way to catch errors. The try..catch..__finally method is now preferred. __finally is not standard for C++ but Microsoft included it in .NET & it works like it does in Java. Besides Richard Simon's 13th chapter, I used these links to get up to speed on the method:


Memory Allocation

malloc is out for managed code. Those who, like me, think of C solutions before C++ may miss it, but the syntax under .NET is easy enough once you see it. And we do have to admit that the old way allowed for too many NULL pointers and unchecked buffers. I believe I have read that version 1.1 of the .NET Framework includes some buffer length checking as part of the management it provides. Unmanaged code, of course, is dependent on the developer writing buffer checks. malloc allocates memory outside the .NET Framework and you cannot create a managed object that way.

Here's what I was going to write:
unsigned char* Buffer;
Buffer = malloc(iBufSize * SizeOf(char));

Instead I write:
Byte Buffer[];
Buffer = new Byte[iBufSize];

Easy enough, huh?