F
Hi,
zuerst mal sorry, dass ich hier eine Frage zu Cygwin stelle, allerdings denke ich mir, passt es hier besser als in ein anderes Unterforum. Wenn nicht, bitte verschieben.
Und zwar versuche ich mit "gcc version 3.4.4 (cygming special)" eine shared Library zu erstellen, was auch wunderbar funktioniert. Hier erstmal der Code dazu:
module.c
#include <stdio.h>
void
module_init(void)
{
printf("Module init\n");
}
void
module_call(char *text)
{
printf("Module call - %s\n", text);
//test();
}
void
module_exit(void)
{
printf("Module exit\n");
}
Makefile module.c
LIB = ../module.so
CFLAGS = -Wall -g -I../..
OBJ = $(patsubst %.c,%.o,$(wildcard *.c))
.PHONY: all all-before all-after clean clean-custom
all: all-before $(LIB) all-after
clean: clean-custom
rm -f $(OBJ) $(LIB)
$(LIB): $(OBJ)
gcc $(CFLAGS) -fPIC -Bdynamic -shared -o $(LIB) $(OBJ)
.c.o:
gcc ${CFLAGS} -o $@ -c $^
main.c
#include <stdio.h>
#include <dlfcn.h>
void
test(void)
{
printf("Test\n");
}
int
main(int argc, char **argv)
{
void *handle;
void (*func_init)(void);
void (*func_call)(char *text);
void (*func_exit)(void);
printf("Init\n");
if((handle = dlopen("./module.so", RTLD_LAZY)) == NULL)
{
printf("Could not load module: %s\n", dlerror());
return 0;
}
if((func_init = dlsym(handle, "module_init")) == NULL)
{
printf("Could not load function: %s\n", dlerror());
dlclose(handle);
return 0;
}
if((func_call = dlsym(handle, "module_call")) == NULL)
{
printf("Could not load function: %s\n", dlerror());
dlclose(handle);
return 0;
}
if((func_exit = dlsym(handle, "module_exit")) == NULL)
{
printf("Could not load function: %s\n", dlerror());
dlclose(handle);
return 0;
}
func_init();
func_call("Function Call ...");
func_exit();
dlclose(handle);
printf("Exit\n");
return 0;
}
Makefile main.c
BIN = Test
CFLAGS = -pipe -Wno-import -Wall -g
CC = gcc
LDL = -ldl
ifeq (CYGWIN, $(findstring CYGWIN, $(shell uname -s)))
LDL =
endif
OBJ = $(patsubst %.c,%.o,$(wildcard *.c))
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
rm -f $(OBJ) $(BIN)
$(BIN): $(OBJ)
@echo "[LD] $@"
gcc $(CFLAGS) $(LDL) -Wl,--export-dynamic $(OBJ) -o $(BIN)
.c.o:
@echo "[CC] $@"
gcc ${CFLAGS} -o $@ -c $^
Wenn ich nun beide Source Files compile und das Programm startet, bekomme ich wie erwartet:
Init
Module init
Module call - Function Call ...
Module exit
Exit
Wenn ich nun aber in der module.c - module_call das ausgeklammerte test(); wieder aktiviere, um damit auf die Funktion void test(void) aus main.c zuzugreifen, funktioniert auch dieses unter Unix (wobei man dafür aber das Compiler Flag -ldl in der Makefile gesetzt haben sollte/muss), aber eben nicht unter Cygwin (dort ist das Flag -ldl nicht bekannt).
Bei Cygwin bekomme ich einen Linkerfehler, dass eben die test() Funktion undefiniert ist.
gcc -Wall -g -I../.. -o module.o -c module.c
module.c: In function module_call': module.c:13: warning: implicit declaration of functiontest'
gcc -Wall -g -I../.. -fPIC -Bdynamic -shared -o ../module.so module.o
module.o: In function module_call': /xModule/mod/module.c:13: undefined reference to_test'
collect2: ld returned 1 exit status
make: *** [../module.so] Error 1
Ich habe zig Stunden im Netz nach der Lösung gesucht und irgendwie das Gefühl bekommen, dass es irgendwie funktionieren könnte, allerdings habe ich nirgendwo eine konkrete Lösung gefunden. Vielleicht hat hier jemand einen Tipp, was ich mal probieren sollte oder einen Hinweis auf die Lösung. Das FAQ zu *.so konnte mir auch nicht weiterhelfen.
Im Moment benutze ich noch Funktionspointer, heißt ich übergebe der module_init ein Pointer auf die Funktion test() aus main.c, was aber auch nicht die Lösung sein kann/sollte.
Wäre klasse, wenn da jemand eine Idee hätte.
Schonmal vielen Dank im voraus.