CFLite

From kJams Wiki
Jump to navigation Jump to search

What is it? CoreFoundation is a cross platform set of APIs that handle international text (unicode + any conversions + search & replace), primitive data types, plist & xml parsing & container classes, with i/o (memory, file, network, virtual device), structured data management of said containers (can wrap with STL): dictionaries (maps), arrays (lists of any kind), sets, and all primitive data types plus calendars, dates, locales, etc. This from the CFLite page:

  • CF provides the fundamental C data types (for example, String, Dictionary, Array, Data and Number) as well as the essential services (such as plug-ins, URL handling and networking) ... [it] provides convenient facilities for importing and exporting these types as part of a rich, flexible data structure known as a property list (a kind of XML).

The thing is so blindingly useful for Unicode string management, managing preferences, internal API dynamic parameter lists, creating, storing, sending and receiving your in-memory data structures as files or via the web, it makes so many things so easy it's a wonder more people aren't using it. Oh, I know why! Nobody's made an easy way to get it going on windows! Sure they *say* it's open source "just compile it on windows"? Well, it's not quite that easy, actually. So I'm going to make it easy for you to use this on Windows. Now you can really write cross platform code to manage your core data types and the ability to easily serialize huge data structures for streaming to / from a file, within memory, or over the web! YAY!

The "Easy" Way

  1. Download my pre-built Windows CFLite 476.17 Binary Installer. It's not really an installer, you have to manually install it.
  2. Unzip it and drop the folder into your WINDOWS directory (typically on your C:\ drive)
  3. On your desktop, right click on "My Computer", click "properties", click "Advanced", click "Environment Variables", then under "System Variables", scroll down to "Path" and select it, click "Edit", then add "%SystemRoot%\CoreFoundation;" to the beginning of the line. (note that if you produce an application for public consumption, you'll have to have your installer do these 2 steps programmatically)
  4. In your Visual Studio (or whatever IDE):
    1. In "C++ / General / Additional Include Directories", add these include paths: "C:\WINDOWS\CoreFoundation" and "C:\WINDOWS\CoreFoundation\GNUCompatability"
    2. In "C++ / Preprocessor / Preprocessor Defninitions", add "__WIN32__"
    3. In "Linker / General / Additional Library Directories", add "C:\WINDOWS\CoreFoundation"
    4. In "Linker / Input / Additional Dependencies", add "CoreFoundation.dll"
    5. In Release configuration only: In "Linker / Optimization / References", change it to "Keep Unreferenced Data"
    6. if you are also linking against QuickTime for winders, set the QT header search path to come AFTER the CF ones
  5. You're done! Enjoy the goodness!

I have added a single function to the Windows version of CF:

void  CFSetLogFile(CFStringRef pathRef);

Call this during your app initialization and it will direct the output CFShow() and CFLog() and friends to that file. Otherwise these functions don't do anything. See CFTest for an example in the CCFLog::operator() routine.

The Hard Way

Build the thing your self. Separate page for that, go here.

Cooperating with QuickTime

QuickTime for windows comes with it's own version of CoreFoundation. If you make a call to a QT function that returns a CF object, you're going to need to release it with QT's version of CFRelease().

void    QT_CFRelease(CFTypeRef cfType)
{
    typedef void    (*QT_CFReleaseProcType)(CFTypeRef cf);
    static QT_CFReleaseProcType        QT_CFReleaseProc = NULL;
   
    if (QT_CFReleaseProc == NULL) {
        HINSTANCE        hinstLib = GetModuleHandleA("QTCF");

        if (hinstLib == NULL) {
            MessageAlert("ERROR: unable to load QTCF");
            return;
        }
     
        // Get function pointer
        QT_CFReleaseProc = (QT_CFReleaseProcType)GetProcAddress(hinstLib, "QTCF_CFRelease");
        if (QT_CFReleaseProc == NULL) {
            MessageAlert("ERROR: unable to find CFRelease");
            return;
        }
    }
   
    if (QT_CFReleaseProc) {
        QT_CFReleaseProc(cfType);
    }
}

Also, if you do any debugging on Windows using Parallels (which is an app running on your mac), then you'll run into the dreaded "Clipboard Chain Lockup". When you're paused in the debugger, the moment you copy and/or paste between the Host and the Guest, your Parallels app will hang (as well as the other app on your host that was the source / destination of the clipboard transfer).

To get around that, use this code.

If you'd like to read the entire crazy saga of how I came to even understand this, see this blog post.