- test7-win32dll began life as an exact copy of test6-ltdlopen. This

revision is exactly the same as the present versin from test6-ltdlopen.
- added: Makefile.in README main.cc main.h module1.cc module2.cc
This commit is contained in:
Bryce Denney 2002-10-14 20:34:13 +00:00
parent d1196d1996
commit d52e44afdb
6 changed files with 207 additions and 0 deletions

View File

@ -0,0 +1,45 @@
top_builddir = ..
top_srcdir = @srcdir@/..
srcdir = @srcdir@
VPATH = @srcdir@
CXX=@CXX@
CXXFLAGS=@CXXFLAGS@ @INCLTDL@
LDFLAGS=@LDFLAGS@ @LT_LDFLAGS@
LIBS=@LIBS@ @LIBLTDL@
LIBTOOL=@LIBTOOL@
RPATH=`pwd`/lib
all: uselib libmodule1.la libmodule2.la
uselib: libmain.la
$(LIBTOOL) $(CXX) $(LDFLAGS) -o uselib libmain.la $(LIBS)
libmain.la: main.lo
$(LIBTOOL) $(CXX) $(LDFLAGS) -o libmain.la main.lo -rpath ${RPATH} $(LIBS)
mkdir -p lib bin
$(LIBTOOL) cp libmain.la ${RPATH}
libmodule1.la: module1.lo libmain.la
$(LIBTOOL) $(CXX) $(LDFLAGS) -o libmodule1.la module1.lo -rpath ${RPATH} libmain.la
mkdir -p lib bin
$(LIBTOOL) cp libmodule1.la ${RPATH}
libmodule2.la: module2.lo libmain.la
$(LIBTOOL) $(CXX) $(LDFLAGS) -o libmodule2.la module2.lo -rpath ${RPATH} libmain.la
mkdir -p lib bin
$(LIBTOOL) cp libmodule2.la ${RPATH}
%.lo: %.cc
$(LIBTOOL) $(CXX) $(CXXFLAGS) -c $<
test:
@echo "*** Running test in `pwd`"
-./uselib
@echo "*** Test done in `pwd`"
clean:
-$(LIBTOOL) rm libmodule1.la module1.lo libmodule2.la module2.lo
rm -rf *.o *.lo *.la uselib.exe bin lib uselib uselib.exe
rm -rf .libs

View File

@ -0,0 +1,48 @@
test6-execsymbols2
Try again to allow the module to reference symbols in the executable.
But this time, eliminate direct symbol references from the executable
to the module, so that the executable can be linked first. I believe
this will work ok for win32 and it's closer to how plugins need to work.
What I think I learned from test5:
> DLLs don't allow any symbols to be undefined at link time. So you have to
> choose the order of how to build things so that each link is complete.
> For a DLL that's used as a shared library, it must be built and linked on
> its own (without the program), with symbols exported. This link must be
> complete, so it can't depend on pieces from the program. Then, the
> program can be linked with the DLL, with the program reading symbols from
> the DLL. It can't go both ways.
>
> For a plugin environment, we want the plugin to be able to call functions
> in the main code, without putting every single thing as a function pointer.
> So the main executable should be built first, with appropriate symbols
> exported, and then the plugin can import those symbols. The main
> executable will find symbols in the DLL using lt_dlopen() and lt_dlsym(),
> which probably maps to LoadLibrary() and GetProcAddress().
module1.lo: In function `module_init(void)':
/home/bryce/bochs-testing/plugin-test/test6-execsymbols2/module1.cc:7: undefined reference to `import stub for register_module(char const *)'
---------------------
ltdl error
Program received signal SIGSEGV, Segmentation fault.
tryall_dlopen_module (handle=0x78f928, prefix=0x0, dirname=0x0,
dlname=0x100d2118 "cygmodule1-0.dll") at ltdl.c:1958
1958 if (dirname[dirname_len -1] == '/')
Current language: auto; currently c
(gdb) where
#0 tryall_dlopen_module (handle=0x78f928, prefix=0x0, dirname=0x0,
dlname=0x100d2118 "cygmodule1-0.dll") at ltdl.c:1958
#1 0x1000249b in find_module (handle=0x78f928, dir=0x0, libdir=0x100d2190
"/home/bryce/bochs-testing/plugin-test/test6-ltdlopen/lib",
dlname=0x100d2118 "cygmodule1-0.dll", old_name=0x100d2130 "libmodule1.a",
installed=0) at ltdl.c:2024
#2 0x100035f8 in try_dlopen (phandle=0x78f958,
filename=0x78f98c "libmodule1.la") at ltdl.c:2798
#3 0x100038a5 in lt_dlopen (filename=0x78f98c "libmodule1.la") at ltdl.c:2893
#4 0x10001143 in load_module (fmt=0x100011fc "lib%s.la",
name=0x100011f4 "module1") at main.cc:19
#5 0x100012bb in main (argc=1, argv=0x100d0e60) at main.cc:46

View File

@ -0,0 +1,61 @@
#include <stdio.h>
#include <ltdl.h>
#define MAIN_DLL_EXPORT
#include "main.h"
const char *version_string = "uselib-test6-1.0";
int register_module (const char *name)
{
printf ("register_module was called by module '%s'\n", name);
return 0;
}
int load_module (const char *fmt, const char *name)
{
char buf[512];
sprintf (buf, fmt, name);
printf ("loading module from %s\n", buf);
lt_dlhandle handle = lt_dlopen (buf);
printf ("handle is %p\n", handle);
if (!handle) {
printf ("lt_dlopen error: %s\n", lt_dlerror ());
return -1;
}
modload_func func = (modload_func) lt_dlsym (handle, "module_init");
printf ("module_init function is at %p\n", func);
if (func != NULL) {
printf ("Calling module_init\n");
(*func)();
} else {
printf ("lt_dlsym error: %s\n", lt_dlerror ());
return -1;
}
return 0;
}
int main (int argc, char **argv)
{
printf ("start\n");
if (lt_dlinit () != 0) {
printf ("lt_dlinit error: %s\n", lt_dlerror ());
return -1;
}
printf ("loading module1\n");
// try to load module1
if (load_module ("lib%s.la", "module1") < 0) {
printf ("load module1 failed\n");
}
if (load_module ("lib%s.la", "module2") < 0) {
printf ("load module2 failed\n");
}
int arg;
for (int arg=1; arg < argc; arg++) {
if (load_module ("%s", argv[arg]) < 0) {
printf ("load %s failed\n", argv[arg]);
}
}
printf ("stop\n");
return 0;
}

View File

@ -0,0 +1,25 @@
#if defined(WIN32) || defined(__CYGWIN__)
# ifdef MAIN_DLL_EXPORT
# ifdef DLL_EXPORT
# warning I will export DLL symbols for MODULE1
# define MAINAPI(type) __declspec(dllexport) type
# endif
# else
# warning I will import DLL symbols for MODULE1
# define MAINAPI(type) __declspec(dllimport) type
# endif
#endif
#ifndef MAINAPI
# warning No DLL import/export is needed
# define MAINAPI(type) type
#endif
typedef void (*modload_func)(void);
MAINAPI(extern const char *) version_string;
MAINAPI(extern int) register_module (const char *name);
extern "C" {
// this prevents C++ name mangling
void module_init ();
};

View File

@ -0,0 +1,13 @@
#include <stdio.h>
#include "main.h"
void module_init ()
{
printf ("module1 init\n");
register_module ("module1");
}
int operate (int a, int b)
{
return a + b;
}

View File

@ -0,0 +1,15 @@
#include <stdio.h>
#include "main.h"
int n_operations = 0;
void module_init ()
{
printf ("module2 init\n");
register_module ("module2");
}
int operate (int a, int b)
{
return a - b;
}