[plt-scheme] multiple definition of dll_entry at 12

From: Ron Stanonik (stanonik at Cogsci.ucsd.edu)
Date: Thu Oct 16 13:04:51 EDT 2003

On Wed, 15 Oct 2003, Matthew Flatt wrote:
> Does your real problem involve printf(), or something else?

My real problem involves printf, select, and getreent.

The scheme extension is an X client, which I previously linked using g++
and plt/lib/gcc/mzdyn.o.  With the change in MzScheme/Cygwin linking
(more steps, dlltool, fixup.o), I tried replacing g++ with mzc.

If I omit -lc during linking, then printf/select/getreent are undefined.
If I include -lc, then dll_entry at 12 is multiple defined.

Does it matter whether I'm using the pre-compiled DrScheme for Windows,
or whether I cvs checkout and build my own using cygwin?  Is the pre-compiled
DrScheme compiled with cygwin or msvc?

Our X client is big, but here's a simple X client that demonstrates
the linking problem.

Thanks,

Ron
stanonik at cogsci.ucsd.edu

============== cygwin makefile ==================

PLT=/home/plt

MZC=${PLT}/mzc.exe

simple.dll: simple.obj
	${MZC} --ld simple.dll simple.obj -L/usr/X11R6/lib -lX11 -lc

simple.obj: simple.c
	${MZC} --cc simple.c

clean:
	-rm -f *.o *.so *.obj *.dll

================= simple.c =====================

#include "escheme.h"
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <sys/time.h>

static int debug = 0;
static int fd;
static fd_set fdset[3];

static int
ready(Scheme_Object *data)
{
	fd_set *fdset;
	int n = 0;
	struct timeval timeout;

	if (debug) fprintf(stderr, "ready fd = %d\n", fd);
	fdset = (fd_set *)data;
	FD_ZERO(&fdset[0]);
	FD_ZERO(&fdset[1]);
	FD_ZERO(&fdset[2]);
	FD_SET(fd, &fdset[0]);
	n = fd + 1;
	timeout.tv_sec = timeout.tv_usec = 0;
	n = select(n, &fdset[0], &fdset[1], &fdset[2], &timeout);
	if (debug) fprintf(stderr, "ready n = %d\n", n);
	return n;
}

static void
wakeup(Scheme_Object *data, void *fds)
{
	void *fdset[3];

	if (debug) fprintf(stderr, "wakeup fd = %d\n", fd);
	fdset[0] = MZ_GET_FDSET(fds, 0);
	fdset[0] = MZ_GET_FDSET(fds, 1);
	fdset[0] = MZ_GET_FDSET(fds, 2);
	MZ_FD_SET(fd, (fd_set *)fdset[0]);
}

Scheme_Object *
sch_simple(int argc, Scheme_Object **argv)
{
        Display *display;
        Window window;
        XEvent event, nextevent;
        int screen;
        unsigned long foreground, background;
	int move = 0, n;

#ifdef CYGWIN
	{
		int fd;
		fd = open("/dev/tty0", 1);
		close(2);
		dup2(fd, 2);
		stderr = fdopen(2, "w");
		close(fd);
		fprintf(stderr, "stderr works\n");
	}
#endif

        /* connect to the X server */
        display = XOpenDisplay("127.0.0.1:0");

        if (display == NULL) {
                scheme_warning("cannot connect to server");
                return scheme_false;
        }
	fd = ConnectionNumber(display);
	fprintf(stderr, "fd = %d\n", fd);

        /* get default screen */
        screen = DefaultScreen (display);

        /* get black and white representation on current screen */
        background = WhitePixel (display, screen);
        foreground = BlackPixel (display, screen);

        /* Create window at (500,500), width 350, height 250, border width
           2, in default root  */
        window = XCreateSimpleWindow (display,
                DefaultRootWindow(display), 500, 500, 350, 250, 2,
                foreground, background);

        if (window == NULL) {
                scheme_warning("cannot open window");
                return scheme_false;
        }

	XSelectInput(display, window,
		PointerMotionMask |
		ButtonPressMask |
		ButtonReleaseMask);

        /* pop this window up on the screen */
        XMapRaised (display, window);

	/* flush X request queue to server */
        XFlush (display);
        while (1) {
		n = scheme_block_until(ready, wakeup, (Scheme_Object *)fdset, 0.1);
		fprintf(stderr, "XNextEvent\n");
                XNextEvent(display, &event);
		switch (event.type) {
			case MotionNotify:
				fprintf(stderr, "motion %d\n", move++);
				while (1) {
					if (QLength(display) == 0)
						break;
					XPeekEvent(display, &nextevent);
					if (nextevent.type != MotionNotify)
						break;
					XNextEvent(display, &event);
				        fprintf(stderr, "motion %d\n", move++);
				}
				break;
			case ButtonPress:
				fprintf(stderr, "press\n");
				break;
			case ButtonRelease:
				fprintf(stderr, "release\n");
				break;
		}
        }

	XDestroyWindow(display, window);
	XCloseDisplay (display);

        return scheme_true;
}

Scheme_Object *scheme_reload(Scheme_Env *env)
{
  scheme_add_global("simple",
    scheme_make_prim_w_arity(sch_simple, "simple", 0, 0), env);
  return scheme_make_string("Hello Simple!");
}

Scheme_Object *scheme_initialize(Scheme_Env *env)
{
  return scheme_reload(env);
}

Scheme_Object *scheme_module_name()
{
  /* This extension doesn't define a module: */
  return scheme_false;
}

================== simple.ss =======================

(load-relative-extension "simple.dll")

(parameterize
  ((current-eventspace (make-eventspace)))
  (thread
    (lambda()
      (simple)
      (display "bye"))))



Posted on the users mailing list.