I don't think this works if there can be more than one copy of ICU on
your system.  (and I am aware of at least one application that does
this...)

I think that the ICU Open Source team has decided to move to a different
model (in the next version) for location of converter data files in the
near future -- one that uses the OS loader to find a converter DLL. 
This avoids the whole environment variable problem (environment
variables, and their counterpart on Win32, registry variables, are evil
for a number of reasons, IMHO -- they are fragile, and cause a lot of
support email when they break..).

So, in other words, the Xerces-C.DLL, ICU-C.DLL, and
ICU_CONVERTER_DATA.DLL will all end up in the same directory, and the OS
will find them without an environment variable hint (or, you can
separate them, and put them on PATH or LIBPATH).  No environment
variables (e.g. ICU_DATA) are required, and so you can have more than
one copy of Xerces and ICU on your system (identical copies or not), and
they don't get mixed up. Installation will also be much simpler (you
don't have to register the DLL's at install time).

Oh, also, I think they retained ICU_DATA as a compile option, if you
really want to still do it that way...I'm not sure about this,
though...Do you think they should retain the environment variable
(ICU_DATA) way, too?

Mike

"Arnold, Curt" wrote:
> 
> The right way to do this under Windows is to put a thin (non-Automation,
> in-process only) COM interface around ICU and support registration with
> DllRegisterServer.  In Xerces, call CoCreateInstance (or similar call) when
> the DLL needs to be loaded and have the stub implementation in Xerces call
> the appropriate virtual function in the interface.
> 
> -----Original Message-----
> From: Michael Mason [mailto:[EMAIL PROTECTED]
> Sent: Thursday, December 09, 1999 8:35 AM
> To: [EMAIL PROTECTED]
> Subject: Re: Non-shared libraries and ICU?
> 
> Rahul Jain wrote:
> >
> > I am all for adding options to makefile(s) to build Xerces-C in different
> > ways as long as these are non-breaking changes. The other issues we have
> > to address while talking about static Xerces-C libraries are:
> >     * what value will be assigned to fgLibLocation
> >     * what is the fallback logic of discovering the ICU converter files.
> > These issues are only relevant in the context of the using ICU and become
> > non-issues if native transcoding option is used.
> 
> Righto. I don't want to go round breaking ICU so I'll leave this aspect
> alone for now.
> 
> >
> > Coming back to fixing the problem of 'panic' when the dynamically
> > loaded Xerces-C library is installed in system default places like
> > '/lib' and '/usr/lib', we should augument the code to look into these
> > directories in addition to the values specified for LD_LIBRARY_PATH.
> >
> > A still better solution is to figure out how we can find out the
> > loaded libraries via a system call (like we currently do under Solaris,
> AIX
> > and HPUX).
> 
> The Linux dlopen man page states that libraries are searched for in
> 
>               A colon-separated list of directories in the user's
>               LD_LIBRARY path environment variable.
> 
>               The     list     of    libraries    specified    in
>               /etc/ld.so.cache.
> 
>               /usr/lib, followed by /lib.
> 
> but I've not found a reference to any way to get Linux to tell us what
> libraries it's currently got loaded. Here's a (slightly longwinded)
> patch which follows dlopen's behaviour in searching for the shared
> library:
> 
> diff -u -u -r1.3 LinuxPlatformUtils.cpp
> --- LinuxPlatformUtils.cpp      1999/11/23 02:00:48     1.3
> +++ LinuxPlatformUtils.cpp      1999/12/09 14:28:28
> @@ -209,49 +209,122 @@
>      char* libEnvVar = getenv(sharedLibEnvVar);
>      char* libPath = NULL;
> 
> -    if (libEnvVar == NULL)
> +    if (libEnvVar != NULL)
>      {
> -        panic(XMLPlatformUtils::Panic_CantFindLib);
> -    }
> +       //
> +       // Its necessary to create a copy because strtok() modifies the
> +       // string as it returns tokens. We don't want to modify the
> string
> +       // returned to by getenv().
> +       //
> 
> -    //
> -    // Its necessary to create a copy because strtok() modifies the
> -    // string as it returns tokens. We don't want to modify the string
> -    // returned to by getenv().
> -    //
> +       libPath = new char[strlen(libEnvVar) + 1];
> +       strcpy(libPath, libEnvVar);
> 
> -    libPath = new char[strlen(libEnvVar) + 1];
> -    strcpy(libPath, libEnvVar);
> +       // First do the searching process for the first directory
> listing
> 
> +       char*  allPaths = libPath;
> +       char*  libPathName;
> 
> -    // First do the searching process for the first directory listing
> +       while ((libPathName = strtok(allPaths, ":")) != NULL)
> +        {
> +           FILE*  dummyFptr = 0;
> +           allPaths = 0;
> 
> -    char*  allPaths = libPath;
> -    char*  libPathName;
> +           char* libfile = new char[strlen(libPathName) +
> strlen(libName) + 2];
> +           strcpy(libfile, libPathName);
> +           strcat(libfile, "/");
> +           strcat(libfile, libName);
> +
> +           dummyFptr = (FILE *) fopen(libfile, "rb");
> +           delete [] libfile;
> +           if (dummyFptr != NULL)
> +            {
> +               fclose(dummyFptr);
> +               libraryPath = new char[strlen(libPathName)+1];
> +               strcpy((char *) libraryPath, libPathName);
> +               break;
> +           }
> 
> -    while ((libPathName = strtok(allPaths, ":")) != NULL)
> -    {
> -        FILE*  dummyFptr = 0;
> -        allPaths = 0;
> +       } // while
> 
> -        char* libfile = new char[strlen(libPathName) + strlen(libName)
> + 2];
> -        strcpy(libfile, libPathName);
> -        strcat(libfile, "/");
> -        strcat(libfile, libName);
> -
> -        dummyFptr = (FILE *) fopen(libfile, "rb");
> -        delete [] libfile;
> -        if (dummyFptr != NULL)
> -        {
> -            fclose(dummyFptr);
> -            libraryPath = new char[strlen(libPathName)+1];
> -            strcpy((char *) libraryPath, libPathName);
> -            break;
> -        }
> +       delete libPath;
> +    }
> 
> -    } // while
> +    // If we've not found it in LD_LIBRARY_PATH, check
> +    // locations specified in /etc/ld.so.conf
> +
> +    if(libraryPath == NULL)
> +    {
> +        FILE* ldsoconf = fopen("/etc/ld.so.conf", "r");
> +       if(ldsoconf != NULL)
> +       {
> +           // Read lines specifying directories to search
> +
> +           char libPathName[256];
> +           while(fgets(libPathName, 256, ldsoconf) != NULL)
> +           {
> +               // Chop off newline if present
> +               char *newline = strrchr(libPathName, '\n');
> +               if(newline != NULL)
> +                   *newline = '\0';
> +
> +               char* libfile = new char[strlen(libPathName) +
> strlen(libName) + 2];
> +               strcpy(libfile, libPathName);
> +               strcat(libfile, "/");
> +               strcat(libfile, libName);
> +
> +               FILE* dummyFptr = (FILE *) fopen(libfile, "rb");
> +               delete [] libfile;
> +               if (dummyFptr != NULL)
> +               {
> +                   fclose(dummyFptr);
> +                   libraryPath = new char[strlen(libPathName)+1];
> +                   strcpy((char *) libraryPath, libPathName);
> +                   break;
> +               }
> +           } // while
> +
> +           fclose(ldsoconf);
> +       }
> +    }
> +
> +    // Finally check /usr/lib and then /lib
> 
> -    delete libPath;
> +    if(libraryPath == NULL)
> +    {
> +        char* libPathName = "/usr/lib";
> +        char* libfile = new char[strlen(libPathName) + strlen(libName)
> + 2];
> +       strcpy(libfile, libPathName);
> +       strcat(libfile, "/");
> +       strcat(libfile, libName);
> +
> +       FILE* dummyFptr = (FILE *) fopen(libfile, "rb");
> +       delete [] libfile;
> +       if (dummyFptr != NULL)
> +       {
> +           fclose(dummyFptr);
> +           libraryPath = new char[strlen(libPathName)+1];
> +           strcpy((char *) libraryPath, libPathName);
> +       }
> +       else
> +       {
> +           // Finally(!) check /lib
> +           char* libPathName = "/lib";
> +           char* libfile = new char[strlen(libPathName) +
> strlen(libName) + 2];
> +           strcpy(libfile, libPathName);
> +           strcat(libfile, "/");
> +           strcat(libfile, libName);
> +
> +           FILE* dummyFptr = (FILE *) fopen(libfile, "rb");
> +           delete [] libfile;
> +           if (dummyFptr != NULL)
> +           {
> +               fclose(dummyFptr);
> +               libraryPath = new char[strlen(libPathName)+1];
> +               strcpy((char *) libraryPath, libPathName);
> +           }
> +       }
> +    }
> 
>      XMLPlatformUtils::fgLibLocation = libraryPath;
> 
> 
> Seems to work okay on my system, with the libray in LD_LIBRARY_PATH, in
> an /etc/ld.so.conf specified directory, and with the library in /lib. I
> hope the indentation and coding style is as expected -- is there an
> Apache group spec for this?
> 
> Someone'll hit us with the Right Way to do this now... ;)
> 
> Best regards,
> Mike.
> 
> --
> Mike Mason, Software Engineer
> XML Script Development Team                    Office: 44-1865-203192
> http://www.xmlscript.org/                      Mobile: 44-7050-288923

Reply via email to