Loading and Using a Plug-in

The final code example in Listing 1-6 shows how a plug-in host would load and use a plug-in.

Listing 1-6 Loading and using a plug-in
// Create a URL that points to the plug-in using a hard-coded path.
CFURLRef url = CFURLCreateWithFileSystemPath( NULL, 
        CFSTR("/homes/joe/Developer/PlugInTest/Plugin.plugin"),
        kCFURLPOSIXPathStyle, TRUE );
// Create a CFPlugin using the URL.
// This step causes the plug-in's types and factories to be
// registered with the system.
// Note that the plug-in's code is not loaded unless the plug-in
// is using dynamic registration.
CFPlugInRef plugin = CFPlugInCreate( NULL, url );
if (!plugin) {
    printf( "Could not create CFPluginRef.\n" );
} else {
    // See if this plug-in implements the Test type.
    CFArrayRef factories =
        CFPlugInFindFactoriesForPlugInType( kTestTypeID );
    // If there are factories for the requested type, attempt to
    // get the IUnknown interface.
    if ((factories != NULL) && (CFArrayGetCount(factories) > 0)) {
        // Get the factory ID for the first location in the array of IDs.
        CFUUIDRef factoryID = CFArrayGetValueAtIndex( factories, 0 );
        // Use the factory ID to get an IUnknown interface.
        // Here the code for the PlugIn is loaded.
        IUnknownVtbl **iunknown = CFPlugInInstanceCreate( NULL,
                            factoryID, kTestTypeID );
        // If this is an IUnknown interface, query for the Test interface.
        if (iunknown) {
            TestInterfaceStruct **interface = NULL;
            (*iunknown)->QueryInterface( iunknown,
                        CFUUIDGetUUIDBytes(kTestInterfaceID), 
                        (LPVOID *)(&interface) );
                // Done with IUnknown.
                (*iunknown)->Release( iunknown );
                // If this is a Test interface, try to call its function.
                if (interface) {
                    (*interface)->fooMe( interface, TRUE );
                    (*interface)->fooMe( interface, FALSE );
                    // Done with test interface.
                    // This causes the plug-in's code to be unloaded.
                    (*interface)->Release( interface );
                } else {
                    printf( "Failed to get interface.\n" );
                }
            } else {
                printf( "Failed to create instance.\n" );
            }
        } else {
            printf( "Could not find any factories.\n" );
        }
        // Release the CFPlugin.
        // Memory for the plug-in is deallocated here.
        CFRelease( plugin );
    }

In the example implementation, CFPlugInFindFactoriesForPlugInType searches all the registered plug-ins and returns the list of all factories that can create the requested type. Once it finds a factory, you use CFPlugInInstanceCreate to create an instance of the TestType and obtain a pointer to its IUnknown interface. Once you have the IUnknown interface, you can query it for the other interfaces it supports. Finally, you can use the interfaces to start invoking the functions.


© 1999 Apple Computer, Inc. (Last Updated 10 December 99)