- add test8-execlass, which defines a C++ class in the executable, and

tests that the modules can access it
This commit is contained in:
Bryce Denney 2002-10-16 13:28:17 +00:00
parent fa853f3b48
commit 4cbcd6550b
7 changed files with 268 additions and 0 deletions

View File

@ -0,0 +1,53 @@
top_builddir = ..
top_srcdir = @srcdir@/..
srcdir = @srcdir@
VPATH = @srcdir@
CXX=@CXX@
CXXFLAGS=@CXXFLAGS@ @INCLTDL@
LDFLAGS=@LDFLAGS@ @LT_LDFLAGS@
LIBS=@LIBS@
LTDL_STATIC_LIB=${top_builddir}/libltdl/.libs/libltdlc.al
LIBTOOL=@LIBTOOL@
RPATH=`pwd`/lib
# select whether to use libtool or win32-specific target.
# This should either be all_libtool or all_win32_dlltool.
all: @PLUGIN_MAKEFILE_TARGET@
########### libtool makefile for all platforms except win32 ###########
all_libtool: uselib libmodule1.la libmodule2.la
uselib: main.lo
$(LIBTOOL) $(CXX) -export-dynamic $(LDFLAGS) -o uselib main.lo $(LIBS) @LIBLTDL@
lib%.la: %.lo
$(LIBTOOL) $(CXX) -module $(LDFLAGS) -o $@ $< -rpath ${RPATH}
mkdir -p lib bin
$(LIBTOOL) cp $@ ${RPATH}
%.lo: %.cc
$(LIBTOOL) $(CXX) $(CXXFLAGS) -c $<
#######################################################################
############# makefile for building plugin DLLs for win32 #############
all_win32_dlltool: uselib.exe module1.dll module2.dll
uselib.exe: main.cc main.h
$(CXX) $(CXXFLAGS) -c -DDLL_EXPORT -o main.o ${srcdir}/main.cc
dlltool --output-def uselib.def main.o
dlltool --dllname uselib.exe --def uselib.def --output-lib uselib.a
dlltool --dllname uselib.exe --output-exp uselib.exp --def uselib.def
$(CXX) $(CXXFLAGS) -o uselib.exe uselib.exp main.o ${LIBS} ${LTDL_STATIC_LIB}
#rm uselib.exp uselib.def
%.dll: %.o uselib.exe
$(CXX) $(CXXFLAGS) -shared -o $@ $< uselib.a
%.o: %.cc
$(CXX) $(CXXFLAGS) -c $<
#######################################################################
include ${top_srcdir}/common-make-defs.txt
clean: clean-common

View File

@ -0,0 +1,4 @@
test8-execlass
Try to put a class definition in the main executable, and have the
modules call it.

View File

@ -0,0 +1,107 @@
#include <stdio.h>
#include <stdlib.h>
#define LT_SCOPE extern /* so that ltdl.h does not export anything */
#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 VARIES{%s}\n", buf);
lt_dlhandle handle = lt_dlopenext (buf);
printf ("handle is VARIES{%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 VARIES{%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;
}
Widget* widgets[10];
void init_widgets ()
{
widgets[0] = new Widget (1, "Fred", 1.01);
widgets[1] = new Widget (2, "Erma", 0.76);
widgets[2] = new Widget (3, "Mikhail", 2.25);
}
int main (int argc, char **argv)
{
printf ("start\n");
init_widgets ();
if (lt_dlinit () != 0) {
printf ("lt_dlinit error: %s\n", lt_dlerror ());
return -1;
}
#ifdef WIN32
const char *module_name_format = "%s";
#else
const char *module_name_format = "lib%s.la";
#endif
printf ("loading module1\n");
// try to load module1
if (load_module (module_name_format, "module1") < 0) {
printf ("load module1 failed\n");
}
if (load_module (module_name_format, "module2") < 0) {
printf ("load module2 failed\n");
}
int arg;
for (int arg=1; arg < argc; arg++) {
if (load_module (module_name_format, argv[arg]) < 0) {
printf ("load %s failed\n", argv[arg]);
}
}
printf ("stop\n");
exit (77);
}
///// Widget class implementation
Widget::Widget(int id, const char* name, float weight)
{
this->id = id;
this->name = name;
this->weight = weight;
}
int Widget::getId ()
{
return id;
}
const char* Widget::getName ()
{
return name;
}
float Widget::getWeight ()
{
return weight;
}
void Widget::print (FILE* fp)
{
fprintf (fp, "[Widget id=%d, name='%s', weight=%.4f]", id, name, weight);
}

View File

@ -0,0 +1,43 @@
#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);
// really, this should only be included in the modules. It would be
// incorrect to call module_init from main, even if the compiler allowed
// you to.
extern "C" {
// this prevents C++ name mangling
void module_init ();
};
class Widget {
int id;
const char *name;
float weight;
public:
Widget(int id, const char* name, float weight);
int getId ();
const char* getName ();
float getWeight ();
void print (FILE*);
};
#define MAX_WIDGETS 10
extern Widget* widgets[MAX_WIDGETS];

View File

@ -0,0 +1,25 @@
#include <stdio.h>
#include "main.h"
void module_init ()
{
printf ("module1 init for main version %s\n", version_string);
register_module ("module1");
if (widgets[2] != NULL) {
printf ("module1 is examining widgets[2]\n");
printf ("module1: widgets[2] name is '%s'\n", widgets[2]->getName ());
}
printf ("module1 will print every widget that it can find\n");
for (int i=0; i<MAX_WIDGETS; i++) {
if (widgets[i]) {
printf ("module1: widgets[%d] is ", i);
widgets[i]->print (stdout);
printf ("\n");
}
}
}
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 for main version %s\n", version_string);
register_module ("module2");
}
int operate (int a, int b)
{
return a - b;
}

View File

@ -0,0 +1,21 @@
start
loading module1
loading module from VARIES{xxx}
handle is VARIES{xxx}
module_init function is at VARIES{xxx}
Calling module_init
module1 init for main version uselib-test6-1.0
register_module was called by module 'module1'
module1 is examining widgets[2]
module1: widgets[2] name is 'Mikhail'
module1 will print every widget that it can find
module1: widgets[0] is [Widget id=1, name='Fred', weight=1.0100]
module1: widgets[1] is [Widget id=2, name='Erma', weight=0.7600]
module1: widgets[2] is [Widget id=3, name='Mikhail', weight=2.2500]
loading module from VARIES{xxx}
handle is VARIES{xxx}
module_init function is at VARIES{xxx}
Calling module_init
module2 init for main version uselib-test6-1.0
register_module was called by module 'module2'
stop