More plugin success

Ken Causey ken at kencausey.com
Fri May 21 23:23:59 UTC 2004


On Fri, 2004-05-21 at 18:12, Jason Dufair wrote:

> It looks like dlopen() may not be the panacea I'd hoped it would be
> since it's apparently not supported on Mac OS X.  But cross-platform
> maintenance of the OpenSSL plugin via header files and linking to dll/so
> files should be very minimal.
> 

This can be worked around.  Here's a bit of code stolen from Nebula
Device that wraps around dll handling code for linux, win32, and Mac
OSX.  I've only actually used the code on Linux so can't confirm that
the other two work.  I'm confident the Win32 code does since there are
commercial projects released for Win32 using this code and the Mac OSX
code should be close at least.

#if defined(__LINUX__)
static void *_dlopen_wrapper(const char *name, bool prefix)
{
    char dll_name[N_MAXPATH];
    if (prefix) {
        strcpy(dll_name,"lib");
        strcat(dll_name,name);
    } else {
        strcpy(dll_name,name);
    }
    strcat(dll_name,".so");
    void *dll = dlopen(dll_name,RTLD_NOW|RTLD_GLOBAL);
    // Caller will handle printing error
    return dll;
}
void *n_dllopen(const char *name)
{
    void *dll = _dlopen_wrapper(name, true);
    if (!dll) {
        char *err1 = n_strdup(dlerror());
        dll = _dlopen_wrapper(name, false);
	if (!dll) {
	    const char *err2 = dlerror();
            n_printf("Could not load dll for '%s'\n", name);
            n_printf("Error was:\n");
            n_printf("%s\n", err1);
            n_printf("%s\n", err2);
	    n_free(err1);
        }
    }
    return dll;
}
#elif defined(__WIN32__)
void *n_dllopen(const char *name)
{
    HINSTANCE dll;
    dll = LoadLibrary((LPCSTR) name);
    if (!dll) {
        // Find out why we failed
        LPVOID lpMsgBuf;
        FormatMessage( 
            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
            FORMAT_MESSAGE_FROM_SYSTEM | 
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            GetLastError(),
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0,
            NULL 
            );
        
        // Display the string.
        n_printf("Could not load dll '%s'\nError was:\n%s\n", name,
lpMsgBuf);

        // Free the buffer.
        LocalFree( lpMsgBuf );
    }
    return (void *) dll;
}
#elif defined(__MACOSX__)
void *n_dllopen(const char *name)
{
    void* result = 0;

    const int kBundleAnyType  = 0;
    const int kBundleNoSubdir = 0;

    CFBundleRef mainBundle = CFBundleGetMainBundle();

    // put the name of the bundle we want in a CFString
    std::string bundleName( name );
    bundleName += ".bundle";
    CFStringRef cfBundleName = CFStringCreateWithCString( NULL,
                                                         
bundleName.c_str(),
                                                         
kCFStringEncodingASCII );

    CFURLRef bundleURL = CFBundleCopyResourceURL( mainBundle,
                                                  cfBundleName, 
                                                  kBundleAnyType, 
                                                  kBundleNoSubdir );

    if ( bundleURL )
    {
        CFBundleRef myBundle = CFBundleCreate( kCFAllocatorDefault,
bundleURL );
        Boolean loaded = CFBundleLoadExecutable( myBundle );
        if ( loaded )
            result = myBundle;
    }
    return result;
}
#else
void *n_dllopen(const char *name)
{
    n_error("nClass::dll_load() not implemented!");
    return NULL;
}
#endif

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20040521/e8bbd6aa/attachment.pgp


More information about the Squeak-dev mailing list