/*
* dyndemo.c
*
* This is a test and demonstration of run-time loading of a module
* of code.
*/
/* Signature: 22391ded 12-Apr-2008 */
#include "config.h"
#include <stdio.h>
#ifdef WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif
extern int variable_in_base;
extern int function_in_base(int x);
/*
* I will make the compiled version of this file big to show that
* it does not get copied into the sub-function in any way... So the
* next new lines just ensure that function_in_base has a very long and
* messy definition. I want to do this so that one can then inspect the
* size of the dyndemo executable and the dynmodule DLL and observe that
* the DLL is small enough that it really can not possibly contain the
* body of "function_in_base".
*/
int p(int x)
{
return 3*x-1;
}
#define q x = p(x);
#define r q q q q q q q q q q
#define s r r r r r r r r r r
#define t s s s s s s s s s s
int function_in_base(int x)
{
t
return 7*x-3;
}
int variable_in_base = 0x12345678;
/*
* So that I can check results I have a copy here of the function
* I put in the loadable module...
*/
int clone(int x)
{
return 3*function_in_base(x) + 1;
}
typedef int onearg(int a);
int main(int argc, char *argv[])
{
onearg *b = NULL;
#ifdef WIN32
HANDLE a = LoadLibrary(".\\dynmodule.dll");
printf("Dynamic loading of test code\na = %p\n", (void *)a);
fflush(stdout);
if (a == 0)
{ DWORD err = GetLastError();
char errbuf[80];
printf("Error code %ld = %lx\n", (long)err, (long)err);
err = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL, err, 0, errbuf, 80, NULL);
if (err != 0) printf("%s", errbuf);
return 0;
}
b = (onearg *)GetProcAddress(a, "callme");
#else
void *a;
printf("Dynamic loading test code\n");
fflush(stdout);
a = dlopen("./dynmodule.so", RTLD_NOW | RTLD_GLOBAL);
printf("a = %p\n", a);
fflush(stdout);
if (a == NULL)
{ printf("Err = <%s>\n", dlerror()); fflush(stdout);
return 0;
}
b = dlsym(a, "callme");
#endif
printf("b = %p\n", b);
fflush(stdout);
if (b == NULL) return 0;
printf("variable as printed from base = %.8x @ %p\n",
variable_in_base, &variable_in_base);
printf("function as printed from base = %p\n",
function_in_base);
/*
* The next 2 lines are expected to display the same numeric value.
*/
printf("b(7) = %x\n", ((onearg *)b)(7));
printf("clone(7) = %x\n", clone(7));
fflush(stdout);
#ifdef WIN32
FreeLibrary(a);
#else
dlclose(a);
#endif
return 0;
}
/* end of dyndemo.c */