[plt-scheme] multiple definition of dll_entry at 12
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"))))