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:
  • C++ FAQ Lite argues for try/catch over the old method.
  • Sun describes Java's error handling ... from which MS drew for .NET, I'm sure.
  • The Temporal Doorway offers one of the more complete discussions on the topic, this in the context of C++ Builder which provides a __finally extension. Borland's __finally block works differently from Microsoft's __finally so don't let that part confuse you. But the discussion of a philosophy & methodology of error-handling is right on the money. His Borland C++Builder example is easily adjusted to Visual C++ .NET for a robust system.
  • Microsoft explains its try-finally syntax.
  • MS explains try-catch-throw syntax.

    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?

  • Williamston Consulting


    IT Solutions for South Carolina Small Business
    .



    Home

    Auto Dealers' Form Software

    Software Development

    Website Development

    Website Advice

    IT Guys' Stuff:

    Certification
    Study Guides

    Programming
    Tips