Difference between revisions of "Esempio libreria eseguibile"

From vsd
Jump to navigation Jump to search
(Created page with "FIle library.c: <source lang=c> // library.c #include <stdio.h> #include <stdlib.h> void foo(int x) { printf("foo(%d)\n", x); } int main(int argc, char **argv) { if...")
 
m
Line 1: Line 1:
FIle library.c:
+
File library.c:
  
 
<source lang=c>
 
<source lang=c>
Line 20: Line 20:
 
</source>
 
</source>
  
 +
gcc command:
 +
<pre>
 +
gcc -fPIC -fPIE -pie -rdynamic -o library library.c
 +
</pre>
  
Credits:
+
library is an executable:
 +
<pre>
 +
$ ./library 44
 +
foo(44)
 +
</pre>
 +
 
 +
but it can be loaded as a shared library.
 +
 
 +
Thi
 +
s is the file dltest.c:
 +
<source lang=C>
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <dlfcn.h>
 +
 
 +
void (*pfoo)(int x);
 +
int (*pmain)(int argc, char **argv);
 +
 
 +
int main(int argc, char *argv[])
 +
{
 +
        void *handle;
 +
        double (*cosine)(double);
 +
        char *error;
 +
 
 +
        handle = dlopen("./library", RTLD_LAZY);
 +
        if (!handle) {
 +
                fprintf(stderr, "%s\n", dlerror());
 +
                exit(EXIT_FAILURE);
 +
        }
 +
 
 +
        dlerror();    /* Clear any existing error */
 +
        printf("dlopen done\n");
 +
        pfoo = (typeof(pfoo)) dlsym(handle, "foo");
 +
        printf("pfoo %p\n",pfoo);
 +
        pmain = (typeof(pmain)) dlsym(handle, "main");
 +
        printf("pmain %p\n",pmain);
 +
 
 +
        pfoo(42);
 +
 
 +
        pmain(argc, argv);
 +
 
 +
        error = dlerror();
 +
        if (error != NULL) {
 +
                fprintf(stderr, "%s\n", error);
 +
                exit(EXIT_FAILURE);
 +
        }
 +
 
 +
        dlclose(handle);
 +
        exit(EXIT_SUCCESS);
 +
}
 +
</source>
 +
 
 +
Let us launch dltest:
 +
<pre>
 +
$ ./dltest 44
 +
dlopen done
 +
pfoo 0x7f04c6da7165
 +
pmain 0x7f04c6da7189
 +
foo(42)
 +
foo(44)
 +
</pre>
 +
 
 +
It works!
 +
 
 +
 
 +
==== Credits: ====
 
* http://marklodato.github.io/2009/10/03/executable-shared-libraries.html
 
* http://marklodato.github.io/2009/10/03/executable-shared-libraries.html
 
* https://unix.stackexchange.com/questions/223385/why-and-how-are-some-shared-libraries-runnable-as-though-they-are-executables
 
* https://unix.stackexchange.com/questions/223385/why-and-how-are-some-shared-libraries-runnable-as-though-they-are-executables

Revision as of 13:37, 16 April 2019

File library.c:

// library.c
#include <stdio.h>
#include <stdlib.h>

void foo(int x) {
    printf("foo(%d)\n", x);
}

int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "USAGE: %s n\n", argv[0]);
        exit(1);
    }
    foo(atoi(argv[1]));
    return 0;
}

gcc command:

gcc -fPIC -fPIE -pie -rdynamic -o library library.c

library is an executable:

$ ./library 44
foo(44)

but it can be loaded as a shared library.

Thi s is the file dltest.c:

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

void (*pfoo)(int x);
int (*pmain)(int argc, char **argv);

int main(int argc, char *argv[])
{
        void *handle;
        double (*cosine)(double);
        char *error;

        handle = dlopen("./library", RTLD_LAZY);
        if (!handle) {
                fprintf(stderr, "%s\n", dlerror());
                exit(EXIT_FAILURE);
        }

        dlerror();    /* Clear any existing error */
        printf("dlopen done\n");
        pfoo = (typeof(pfoo)) dlsym(handle, "foo");
        printf("pfoo %p\n",pfoo);
        pmain = (typeof(pmain)) dlsym(handle, "main");
        printf("pmain %p\n",pmain);

        pfoo(42);

        pmain(argc, argv);

        error = dlerror();
        if (error != NULL) {
                fprintf(stderr, "%s\n", error);
                exit(EXIT_FAILURE);
        }

        dlclose(handle);
        exit(EXIT_SUCCESS);
}

Let us launch dltest:

$ ./dltest 44
dlopen done
pfoo 0x7f04c6da7165
pmain 0x7f04c6da7189
foo(42)
foo(44)

It works!


Credits: