Win32 patch for dll and net backend

Petter Reinholdtsen (pere@hungry.com)
Fri, 9 Apr 1999 14:46:43 +0200

After reading the source for WinSANE 0.9, I started restructuring the
net backend, and intregrating Win32 changes to the dll backend.

The most importand change all backends should do, is add DLLEXPORT and
DLLCALL before all DLL entry points.

I beleave the dll backend should be functioning, but I have not been
able to test it - I lack a windows box. :-) It also includes some
cleanup, which should make the implementation smaller and better.

The net changes are mostly copied from WinSANE 0.9, but I did some
changes to make it more portable.

This patch is also available from
<URL:http://www.student.uit.no/~pere/linux/>.

David, are you interested in including these patches in 1.01, or
should it be postponed until later?

diff -ru sane-pre1.01-4/ChangeLog sane-pre1.01-4-pere/ChangeLog
--- sane-pre1.01-4/ChangeLog Sun Apr 4 01:17:20 1999
+++ sane-pre1.01-4-pere/ChangeLog Fri Apr 9 14:25:28 1999
@@ -1,3 +1,8 @@
+1999-04-08 Petter Reinholdtsen <pere@td.org.uit.no>
+ * include/sane/config.h.in include/sane/sane.h backend/dll.c
+ backend/net.c: Added initial Win32 patches. Win32 dll support
+ should be complete.
+
1999-04-03 David Mosberger-Tang <David.Mosberger@acm.org>

* include/sane/sanei_debug.h: Define sanei_debug_BACKEND_NAME only
diff -ru sane-pre1.01-4/backend/dll.c sane-pre1.01-4-pere/backend/dll.c
--- sane-pre1.01-4/backend/dll.c Sun Feb 28 00:51:37 1999
+++ sane-pre1.01-4-pere/backend/dll.c Fri Apr 9 01:20:39 1999
@@ -54,6 +54,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif

#if defined(HAVE_DLOPEN) && defined(HAVE_DLFCN_H)
# include <dlfcn.h>
@@ -68,12 +71,29 @@
# ifndef RTLD_LAZY
# define RTLD_LAZY 1
# endif
+# if defined(_AIX)
+# define DLL_PATH_ENV "LIBPATH"
+# else
+# define DLL_PATH_ENV "LD_LIBRARY_PATH"
+# endif
+# define DLL_PATH_SEPARATOR ":"
+# define DLL_SLASH "/"
+# define DLL_NAME "libsane-%s.so." STRINGIFY(V_MAJOR)
# define HAVE_DLL
-#endif
-
+#elif defined (HAVE_SHL_LOAD) && defined(HAVE_DL_H)
/* HP/UX DLL support */
-#if defined (HAVE_SHL_LOAD) && defined(HAVE_DL_H)
# include <dl.h>
+# define DLL_PATH_ENV "SHLIB_PATH"
+# define DLL_PATH_SEPARATOR ":"
+# define DLL_SLASH "/"
+# define DLL_NAME "libsane-%s.sl." STRINGIFY(V_MAJOR)
+# define HAVE_DLL
+#elif defined(HAVE_LOADLIBRARY)
+/* Win32 */
+# define DLL_PATH_ENV "PATH"
+# define DLL_PATH_SEPARATOR ";"
+# define DLL_SLASH "\\"
+# define DLL_NAME "sane%s.dll"
# define HAVE_DLL
#endif

@@ -230,24 +250,11 @@
load (struct backend *be)
{
#ifdef HAVE_DLL
- int mode = 0;
char *funcname, *src, *dir, *path = 0;
char libname[PATH_MAX];
int i;
FILE *fp = 0;

-#if defined(HAVE_DLOPEN)
-# define PREFIX "libsane-"
-# define POSTFIX ".so.%u"
- mode = getenv ("LD_BIND_NOW") ? RTLD_NOW : RTLD_LAZY;
-#elif defined(HAVE_SHL_LOAD)
-# define PREFIX "libsane-"
-# define POSTFIX ".sl.%u"
- mode = BIND_DEFERRED;
-#else
-# error "Tried to compile unsupported DLL."
-#endif /* HAVE_DLOPEN */
-
DBG(1, "loading backend %s\n", be->name);

/* initialize all ops to "unsupported" so we can "use" the backend
@@ -260,28 +267,22 @@
dir = STRINGIFY(LIBDIR);
while (dir)
{
- snprintf (libname, sizeof (libname), "%s/"PREFIX"%s"POSTFIX,
- dir, be->name, V_MAJOR);
+ snprintf (libname, sizeof (libname), "%s" DLL_SLASH DLL_NAME,
+ dir, be->name);
fp = fopen (libname, "r");
if (fp)
break;

if (!path)
{
- path = getenv ("LD_LIBRARY_PATH");
- if (!path)
- {
- path = getenv ("SHLIB_PATH"); /* for HP-UX */
- if (!path)
- path = getenv ("LIBPATH"); /* for AIX */
- }
+ path = getenv (DLL_PATH_ENV);
if (!path)
break;

path = strdup (path);
src = path;
}
- dir = strsep (&src, ":");
+ dir = strsep (&src, DLL_PATH_SEPARATOR);
}
if (path)
free (path);
@@ -294,9 +295,11 @@
DBG(2, "dlopen()ing `%s'\n", libname);

#ifdef HAVE_DLOPEN
- be->handle = dlopen (libname, mode);
+ be->handle = dlopen (libname, getenv ("LD_BIND_NOW") ? RTLD_NOW : RTLD_LAZY);
#elif defined(HAVE_SHL_LOAD)
- be->handle = (shl_t)shl_load (libname, mode, 0L);
+ be->handle = (shl_t)shl_load (libname, BIND_DEFERRED, 0L);
+#elif defined(HAVE_LOADLIBRARY)
+ be->handle = LoadLibrary(libname);
#else
# error "Tried to compile unsupported DLL."
#endif /* HAVE_DLOPEN */
@@ -319,6 +322,8 @@
op = (void *(*)()) dlsym (be->handle, funcname + 1);
#elif defined(HAVE_SHL_LOAD)
shl_findsym ((shl_t*)&(be->handle), funcname + 1, TYPE_UNDEFINED, &op);
+#elif defined(HAVE_LOADLIBRARY)
+ op = GetProcAddress(be->handle, funcname + 1);
#else
# error "Tried to compile unsupported DLL."
#endif /* HAVE_DLOPEN */
@@ -331,6 +336,8 @@
op = (void *(*)()) dlsym (be->handle, funcname);
#elif defined(HAVE_SHL_LOAD)
shl_findsym (be->handle, funcname, TYPE_UNDEFINED, &op);
+#elif defined(HAVE_LOADLIBRARY)
+ op = GetProcAddress(be->handle, funcname);
#else
# error "Tried to compile unsupported DLL."
#endif /* HAVE_DLOPEN */
@@ -343,8 +350,6 @@

return SANE_STATUS_GOOD;

-# undef PREFIX
-# undef POSTFIX
#else /* HAVE_DLL */
DBG(1, "load: ignoring attempt to load `%s'; compiled without dl support\n",
be->name);
@@ -379,7 +384,7 @@
return SANE_STATUS_GOOD;
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
{
char backend_name[PATH_MAX];
@@ -425,7 +430,7 @@
return SANE_STATUS_GOOD;
}

-void
+DLLEXPORT void DLLCALL
sane_exit (void)
{
struct backend *be, *next;
@@ -441,15 +446,18 @@
(*be->op[OP_EXIT]) ();
#ifdef HAVE_DLL

-#ifdef HAVE_DLOPEN
if (be->handle)
- dlclose (be->handle);
+ {
+#ifdef HAVE_DLOPEN
+ dlclose (be->handle);
#elif defined(HAVE_SHL_LOAD)
- if (be->handle)
- shl_unload(be->handle);
+ shl_unload(be->handle);
+#elif defined(HAVE_LOADLIBRARY)
+ FreeLibrary(be->handle);
#else
# error "Tried to compile unsupported DLL."
#endif /* HAVE_DLOPEN */
+ }

#endif /* HAVE_DLL */
}
@@ -468,7 +476,7 @@
(assuming you know the name of the backend/device). This is
appropriate for the command-line interface of SANE, for example.
*/
-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
{
static int devlist_size = 0, devlist_len = 0;
@@ -549,7 +557,7 @@
return SANE_STATUS_GOOD;
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
{
const char *be_name, *dev_name;
@@ -619,7 +627,7 @@
return SANE_STATUS_GOOD;
}

-void
+DLLEXPORT void DLLCALL
sane_close (SANE_Handle handle)
{
struct meta_scanner *s = handle;
@@ -629,7 +637,7 @@
free (s);
}

-const SANE_Option_Descriptor *
+DLLEXPORT const SANE_Option_Descriptor * DLLCALL
sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
{
struct meta_scanner *s = handle;
@@ -638,7 +646,7 @@
return (*s->be->op[OP_GET_OPTION_DESC]) (s->handle, option);
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_control_option (SANE_Handle handle, SANE_Int option,
SANE_Action action, void *value, SANE_Word * info)
{
@@ -650,7 +658,7 @@
value, info);
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
{
struct meta_scanner *s = handle;
@@ -659,7 +667,7 @@
return (long) (*s->be->op[OP_GET_PARAMS]) (s->handle, params);
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_start (SANE_Handle handle)
{
struct meta_scanner *s = handle;
@@ -668,7 +676,7 @@
return (long) (*s->be->op[OP_START]) (s->handle);
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_read (SANE_Handle handle, SANE_Byte * data, SANE_Int max_length,
SANE_Int * length)
{
@@ -679,7 +687,7 @@
return (long) (*s->be->op[OP_READ]) (s->handle, data, max_length, length);
}

-void
+DLLEXPORT void DLLCALL
sane_cancel (SANE_Handle handle)
{
struct meta_scanner *s = handle;
@@ -688,7 +696,7 @@
(*s->be->op[OP_CANCEL]) (s->handle);
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
{
struct meta_scanner *s = handle;
@@ -697,7 +705,7 @@
return (long) (*s->be->op[OP_SET_IO_MODE]) (s->handle, non_blocking);
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
{
struct meta_scanner *s = handle;
diff -ru sane-pre1.01-4/backend/net.c sane-pre1.01-4-pere/backend/net.c
--- sane-pre1.01-4/backend/net.c Sat Apr 3 06:43:01 1999
+++ sane-pre1.01-4-pere/backend/net.c Fri Apr 9 13:02:41 1999
@@ -63,6 +63,26 @@
#include <netinet/in.h>
#include <netdb.h> /* OS/2 needs this _after_ <netinet/in.h>, grrr... */

+#ifdef HAVE_WINDOWS_H
+# define HAVE_WIN32
+# include <windows.h>
+# include <io.h>
+# include <winsock.h>
+# include <malloc.h>
+# define NETREAD recv
+# define NETWRITE send
+# define NETCLOSE closesocket
+# warning "Username is hardcoded!"
+# define USERNAME "hardcoded"
+# define SOCKET_OK(s) (s != INVALID_SOCKET)
+#else
+# define NETREAD read
+# define NETWRITE write
+# define NETCLOSE close
+# define USERNAME getlogin()
+# define SOCKET_OK(s) (s >= 0)
+#endif
+
#include <sane/sane.h>
#include <sane/sanei.h>
#include <sane/sanei_net.h>
@@ -149,7 +169,7 @@
}

dev->ctl = socket (dev->addr.sa_family, SOCK_STREAM, 0);
- if (dev->ctl < 0)
+ if (!SOCKET_OK(dev->ctl))
{
DBG(1, "connect_dev: failed to obtain socket (%s)\n", strerror (errno));
dev->ctl = -1;
@@ -188,13 +208,13 @@

sanei_w_init (&dev->wire, sanei_codec_bin_init);
dev->wire.io.fd = dev->ctl;
- dev->wire.io.read = read;
- dev->wire.io.write = write;
+ dev->wire.io.read = NETREAD;
+ dev->wire.io.write = NETWRITE;

/* exchange version codes with the server: */
req.version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR,
SANEI_NET_PROTOCOL_VERSION);
- req.username = getlogin ();
+ req.username = USERNAME;
sanei_w_call (&dev->wire, SANE_NET_INIT,
(WireCodecFunc) sanei_w_init_req, &req,
(WireCodecFunc) sanei_w_init_reply, &reply);
@@ -229,7 +249,7 @@
return SANE_STATUS_GOOD;

fail:
- close (dev->ctl);
+ NETCLOSE (dev->ctl);
dev->ctl = -1;
return SANE_STATUS_IO_ERROR;
}
@@ -261,7 +281,7 @@
s->hw->auth_active = 0;
if (s->data >= 0)
{
- close (s->data);
+ NETCLOSE (s->data);
s->data = -1;
}
return SANE_STATUS_CANCELLED;
@@ -294,7 +314,7 @@
}
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
{
char device_name[PATH_MAX];
@@ -305,6 +325,27 @@

DBG_INIT();

+#ifdef HAVE_WIN32
+ {
+ WSADATA wsadata;
+ WORD wVer;
+
+ mVer = MAKEWORD(1,1);
+ if (0 != WSAStartup(wVer, &wsadata))
+ {
+ DBG(1, "WSAStartup(1.1, ptr) failed.");
+ return SANE_STATUS_UNSUPPORTED; /* XXX check this error value */
+ }
+
+ /* Check WINSOCK.DLL version */
+ if (1 != LOBYTE(wsadata.mVersion) || 1 != HIBYTE(wsadata.mVersion))
+ {
+ DBG(1, "WINSOCK.DLL does not support v1.1.");
+ return SANE_STATUS_UNSUPPORTED; /* XXX check this error value */
+ }
+ }
+#endif
+
auth_callback = authorize;

if (version_code)
@@ -318,7 +359,7 @@
saned_port = htons (6566);
DBG(1,
"init: could not find `sane' service (%s); using default port %d\n",
- strerror (errno), htons (saned_port));
+ strerror (errno), htons ((unsigned short)saned_port));
}

fp = sanei_config_open (NET_CONFIG_FILE);
@@ -354,7 +395,7 @@
return SANE_STATUS_GOOD;
}

-void
+DLLEXPORT void DLLCALL
sane_exit (void)
{
Net_Scanner *handle, *next_handle;
@@ -382,10 +423,19 @@
sanei_w_call (&dev->wire, SANE_NET_EXIT,
(WireCodecFunc) sanei_w_void, 0,
(WireCodecFunc) sanei_w_void, 0);
- close (dev->ctl);
+ NETCLOSE (dev->ctl);
}
free (dev);
}
+#ifdef HAVE_WIN32
+ /* Release Windows socket DLL */
+ if (SOCKET_ERROR == WSACleanup())
+ if (WSAEINPROGRESS == WSAGetLastError())
+ {
+ WSACancelBlockingCall();
+ WSACleanup();
+ }
+#endif
}

/* Note that a call to get_devices() implies that we'll have to
@@ -394,7 +444,7 @@
backend/device). This is appropriate for the command-line
interface of SANE, for example.
*/
-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
{
static int devlist_size = 0, devlist_len = 0;
@@ -500,7 +550,7 @@
return SANE_STATUS_GOOD;
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
{
SANE_Open_Reply reply;
@@ -609,7 +659,7 @@
return SANE_STATUS_GOOD;
}

-void
+DLLEXPORT void DLLCALL
sane_close (SANE_Handle handle)
{
Net_Scanner *prev, *s;
@@ -636,11 +686,11 @@
(WireCodecFunc) sanei_w_word, &s->handle,
(WireCodecFunc) sanei_w_word, &ack);
if (s->data >= 0)
- close (s->data);
+ NETCLOSE (s->data);
free (s);
}

-const SANE_Option_Descriptor *
+DLLEXPORT const SANE_Option_Descriptor * DLLCALL
sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
{
Net_Scanner *s = handle;
@@ -658,7 +708,7 @@
return s->opt.desc[option];
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_control_option (SANE_Handle handle, SANE_Int option,
SANE_Action action, void *value, SANE_Word * info)
{
@@ -733,7 +783,7 @@
return status;
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
{
Net_Scanner *s = handle;
@@ -755,7 +805,7 @@
return status;
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_start (SANE_Handle handle)
{
Net_Scanner *s = handle;
@@ -779,7 +829,7 @@
}

fd = socket (s->hw->addr.sa_family, SOCK_STREAM, 0);
- if (fd < 0)
+ if (!SOCKET_OK(fd))
{
DBG(1, "start: socket() failed (%s)\n", strerror (errno));
return SANE_STATUS_IO_ERROR;
@@ -802,7 +852,7 @@

if (status != SANE_STATUS_GOOD)
{
- close (fd);
+ NETCLOSE (fd);
return status;
}
}
@@ -813,7 +863,7 @@
if (connect (fd, (struct sockaddr *) &sin, len) < 0)
{
DBG(1, "start: connect() failed (%s)\n", strerror (errno));
- close (fd);
+ NETCLOSE (fd);
return SANE_STATUS_IO_ERROR;
}
shutdown (fd, 1);
@@ -823,7 +873,7 @@
return status;
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_read (SANE_Handle handle, SANE_Byte * data, SANE_Int max_length,
SANE_Int * length)
{
@@ -842,7 +892,7 @@
{
/* boy, is this painful or what? */

- nread = read (s->data, s->reclen_buf + s->reclen_buf_offset,
+ nread = NETREAD (s->data, s->reclen_buf + s->reclen_buf_offset,
4 - s->reclen_buf_offset);
if (nread < 0)
{
@@ -873,7 +923,7 @@
fcntl (s->data, F_SETFL, 0);

/* read the status byte: */
- if (read (s->data, &ch, sizeof (ch)) != 1)
+ if (NETREAD (s->data, &ch, sizeof (ch)) != 1)
ch = SANE_STATUS_IO_ERROR;
do_cancel (s);
return (SANE_Status) ch;
@@ -883,7 +933,7 @@
if (max_length > s->bytes_remaining)
max_length = s->bytes_remaining;

- nread = read (s->data, data, max_length);
+ nread = NETREAD (s->data, data, max_length);
if (nread < 0)
{
if (errno == EAGAIN)
@@ -899,7 +949,7 @@
return SANE_STATUS_GOOD;
}

-void
+DLLEXPORT void DLLCALL
sane_cancel (SANE_Handle handle)
{
Net_Scanner *s = handle;
@@ -911,7 +961,7 @@
do_cancel (s);
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
{
Net_Scanner *s = handle;
@@ -925,7 +975,7 @@
return SANE_STATUS_GOOD;
}

-SANE_Status
+DLLEXPORT SANE_Status DLLCALL
sane_get_select_fd (SANE_Handle handle, SANE_Int *fd)
{
Net_Scanner *s = handle;
diff -ru sane-pre1.01-4/include/sane/config.h.in sane-pre1.01-4-pere/include/sane/config.h.in
--- sane-pre1.01-4/include/sane/config.h.in Tue Mar 9 06:50:03 1999
+++ sane-pre1.01-4-pere/include/sane/config.h.in Fri Apr 9 01:02:29 1999
@@ -335,4 +335,9 @@
# define __EXTENSIONS__
#endif

+#ifdef _WINDOWS
+# define HAVE_WINDOWS_H
+# define HAVE_LOADLIBRARY
+#endif
+
#endif /* SANE_CONFIG_H */
diff -ru sane-pre1.01-4/include/sane/sane.h sane-pre1.01-4-pere/include/sane/sane.h
--- sane-pre1.01-4/include/sane/sane.h Sun Feb 28 00:54:08 1999
+++ sane-pre1.01-4-pere/include/sane/sane.h Fri Apr 9 00:37:53 1999
@@ -30,6 +30,14 @@
#define SANE_FALSE 0
#define SANE_TRUE 1

+#if defined(_WINDOWS)
+# define DLLEXPORT __declspec( dllexport )
+# define DLLCALL __cdecl
+#else
+# define DLLEXPORT
+# define DLLCALL
+#endif
+
typedef unsigned char SANE_Byte;
typedef int SANE_Word;
typedef SANE_Word SANE_Bool;
@@ -185,29 +193,29 @@
SANE_Char username[SANE_MAX_USERNAME_LEN],
SANE_Char password[SANE_MAX_PASSWORD_LEN]);

-extern SANE_Status sane_init (SANE_Int * version_code,
+extern DLLEXPORT SANE_Status DLLCALL sane_init (SANE_Int * version_code,
SANE_Auth_Callback authorize);
-extern void sane_exit (void);
-extern SANE_Status sane_get_devices (const SANE_Device *** device_list,
+extern DLLEXPORT void DLLCALL sane_exit (void);
+extern DLLEXPORT SANE_Status DLLCALL sane_get_devices (const SANE_Device *** device_list,
SANE_Bool local_only);
-extern SANE_Status sane_open (SANE_String_Const devicename,
+extern DLLEXPORT SANE_Status DLLCALL sane_open (SANE_String_Const devicename,
SANE_Handle * handle);
-extern void sane_close (SANE_Handle handle);
-extern const SANE_Option_Descriptor *
- sane_get_option_descriptor (SANE_Handle handle, SANE_Int option);
-extern SANE_Status sane_control_option (SANE_Handle handle, SANE_Int option,
+extern DLLEXPORT void DLLCALL sane_close (SANE_Handle handle);
+extern DLLEXPORT const SANE_Option_Descriptor *
+ DLLCALL sane_get_option_descriptor (SANE_Handle handle, SANE_Int option);
+extern DLLEXPORT SANE_Status DLLCALL sane_control_option (SANE_Handle handle, SANE_Int option,
SANE_Action action, void *value,
SANE_Int * info);
-extern SANE_Status sane_get_parameters (SANE_Handle handle,
+extern DLLEXPORT SANE_Status DLLCALL sane_get_parameters (SANE_Handle handle,
SANE_Parameters * params);
-extern SANE_Status sane_start (SANE_Handle handle);
-extern SANE_Status sane_read (SANE_Handle handle, SANE_Byte * data,
+extern DLLEXPORT SANE_Status DLLCALL sane_start (SANE_Handle handle);
+extern DLLEXPORT SANE_Status DLLCALL sane_read (SANE_Handle handle, SANE_Byte * data,
SANE_Int max_length, SANE_Int * length);
-extern void sane_cancel (SANE_Handle handle);
-extern SANE_Status sane_set_io_mode (SANE_Handle handle,
+extern DLLEXPORT void DLLCALL sane_cancel (SANE_Handle handle);
+extern DLLEXPORT SANE_Status DLLCALL sane_set_io_mode (SANE_Handle handle,
SANE_Bool non_blocking);
-extern SANE_Status sane_get_select_fd (SANE_Handle handle,
+extern DLLEXPORT SANE_Status DLLCALL sane_get_select_fd (SANE_Handle handle,
SANE_Int * fd);
-extern SANE_String_Const sane_strstatus (SANE_Status status);
+extern DLLEXPORT SANE_String_Const DLLCALL sane_strstatus (SANE_Status status);

#endif /* sane_h */

-- 
##>  Petter Reinholdtsen <##    | pere@td.org.uit.no
 O-  <SCRIPT Language="Javascript">window.close()</SCRIPT>
http://www.hungry.com/~pere/    | Go Mozilla, go! Go!

--
Source code, list archive, and docs: http://www.mostang.com/sane/
To unsubscribe: echo unsubscribe sane-devel | mail majordomo@mostang.com