glib/iconv : delayed dependency



the attached new file adds truely dynamic linking of iconv.dll
to glib for win32. It is simply wrapping the three used
iconv functions, to resolve them not at compile time, but
at runtime.

This gives the opportunity to distribute recent Gtk+ binary 
versions without just another 0.5 MB dependency.

Every program not using the gconvert facility will not
notice the difference (while the internet providers
providing slow timebased connections will :-)

Programs using the gconvert facility should check the return 
values of the convert functions, cause these functions now may 
fail because of a missing iconv.dll. (It is spitting a g_warning
then.)

If the iconv.dll is available everthing will work as before.

Ok to commit ?

	Hans
/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * icon-win32.c: Convert between character sets using 
 *               truely dynamic iconv.dll linking
 *
 * Copyright 2001, Hans Breuer <hans breuer org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <iconv.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#include "glib.h"
#include "config.h"

#ifdef G_PLATFORM_WIN32
#define STRICT
#include <windows.h>
#undef STRICT
#endif

#include "glibintl.h"

/*
 * function pointer prototypes
 */
typedef iconv_t (* PFN_iconv_open) (const char*, const char* );
typedef size_t (* PFN_iconv) (iconv_t, char* *, size_t *,
                              char * *, size_t *);
typedef int (* PFN_iconv_close) (iconv_t);

/*
 * function pointer variables
 */
static PFN_iconv_open pfn_iconv_open = NULL;
static PFN_iconv pfn_iconv = NULL;
static PFN_iconv_close pfn_iconv_close = NULL;

static gboolean dynamic_iconv_init (void)
{
  static gboolean init_done = FALSE;

  if (!init_done)
    {
      HMODULE h = NULL;
      /* first try with version number in name */
      h = LoadLibrary ("iconv-1.3.dll");
      if (!h)
        h = LoadLibrary ("iconv.dll");

      if (!h)
        g_warning ("Failed to load iconv-1.3.dll or iconv.dll.");
      else
        {
          pfn_iconv_open = (PFN_iconv_open) GetProcAddress (h, "libiconv_open");
          if (!pfn_iconv_open)
            g_warning ("Missing entry point iconv_open().");

          pfn_iconv = (PFN_iconv) GetProcAddress (h, "libiconv");
          if (!pfn_iconv)
            g_warning ("Missing entry point iconv().");

          pfn_iconv_close = (PFN_iconv_close) GetProcAddress (h, "libiconv_close");
          if (!pfn_iconv_close)
            g_warning ("Missing entry point iconv_close().");
        }
      init_done = TRUE;
    }

  return (pfn_iconv_open && pfn_iconv && pfn_iconv_close);
}

iconv_t 
iconv_open (const char* tocode, const char* fromcode)
{
  if (dynamic_iconv_init() && pfn_iconv_open)
    return pfn_iconv_open (tocode, fromcode);

  errno = EINVAL;
  return (iconv_t)(-1);
}

size_t 
iconv (iconv_t icd,
       char* * inbuf, size_t *inbytesleft,
       char* * outbuf, size_t *outbytesleft)
{
  if (dynamic_iconv_init() && pfn_iconv)
    return pfn_iconv (icd, inbuf, inbytesleft, outbuf, outbytesleft);

  errno = EINVAL;
  return 0;
}

int 
iconv_close (iconv_t icd)
{
  if (dynamic_iconv_init() && pfn_iconv_close)
    return pfn_iconv_close (icd);

  errno = EINVAL;
  return 0;
}
-------- Hans "at" Breuer "dot" Org -----------
Tell me what you need, and I'll tell you how to 
get along without it.                -- Dilbert


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]