From: DeMarcus on
Hi,

I have a program written in C++ with global variables. Now I want to
make those global variables available to shared libraries linked in to
the software.

I've compiled with g++ 4.5.0 using -rdynamic but when I load the library
with dlopen() i get the error message: "undefined symbol: __dso_handle".

Doing nm MyApp | grep __dso_handle gives me
000000085a438 d __dso_handle which means __dso_handle is internal.

What am I doing wrong? Is there a good tutorial for linking C++ code
dynamically?

Thanks,
Daniel


PS. If there is a better group for questions like this, please direct me
there. Thanks.

From: Ersek, Laszlo on
On Mon, 2 Aug 2010, DeMarcus wrote:

> I have a program written in C++ with global variables. Now I want to
> make those global variables available to shared libraries linked in to
> the software.
>
> I've compiled with g++ 4.5.0 using -rdynamic but when I load the library
> with dlopen() i get the error message: "undefined symbol: __dso_handle".
>
> Doing nm MyApp | grep __dso_handle gives me
> 000000085a438 d __dso_handle which means __dso_handle is internal.
>
> What am I doing wrong? Is there a good tutorial for linking C++ code
> dynamically?

The following works for me on Debian Lenny.

Cheers,
lacos

--- /dev/null 2010-08-02 09:36:27.503133517 +0200
+++ app.h 2010-08-02 23:44:25.000000000 +0200
@@ -0,0 +1,10 @@
+class My
+{
+ int i;
+
+ public:
+ void set(int i);
+ int get();
+};
+
+extern My my;
--- /dev/null 2010-08-02 09:36:27.503133517 +0200
+++ lib.cpp 2010-08-03 00:03:47.000000000 +0200
@@ -0,0 +1,11 @@
+#define _XOPEN_SOURCE 600
+
+#include "app.h"
+
+extern "C" void foo();
+
+void
+foo()
+{
+ my.set(1);
+}
--- /dev/null 2010-08-02 09:36:27.503133517 +0200
+++ app.cpp 2010-08-03 00:19:51.000000000 +0200
@@ -0,0 +1,68 @@
+#define _XOPEN_SOURCE 600
+
+#include <dlfcn.h> /* dlopen() */
+#include <stdio.h> /* fprintf() */
+#include <stdlib.h> /* EXIT_FAILURE */
+#include <errno.h> /* errno */
+#include <string.h> /* strerror() */
+
+#include "app.h"
+
+
+void
+My::set(int i)
+{
+ this->i = i;
+}
+
+int
+My::get()
+{
+ return this->i;
+}
+
+
+My my;
+
+extern "C" typedef void foofun_type(); /* See C++03 7.5 p4. */
+
+int
+main()
+{
+ int ret;
+ void *handle;
+
+ ret = EXIT_FAILURE;
+
+ handle = dlopen("./lib.so", RTLD_NOW | RTLD_LOCAL);
+ if (0 == handle) {
+ (void)fprintf(stderr, "dlopen(): %s\n", dlerror());
+ }
+ else {
+ void *sym;
+
+ sym = dlsym(handle, "foo");
+ if (0 == sym) {
+ (void)fprintf(stderr, "dlsym(): %s\n", dlerror());
+ }
+ else {
+ foofun_type *foofun; /* pointer to C function */
+
+ *(void **)&foofun = sym;
+ (*foofun)();
+ if (0 > fprintf(stdout, "%d\n", my.get()) || EOF == fflush(stdout)) {
+ (void)fprintf(stderr, "fprintf()/fflush(): %s\n", strerror(errno));
+ }
+ else {
+ ret = EXIT_SUCCESS;
+ }
+ }
+
+ if (0 != dlclose(handle)) {
+ (void)fprintf(stderr, "dlclose(): %s\n", dlerror());
+ ret = EXIT_FAILURE;
+ }
+ }
+
+ return ret;
+}
--- /dev/null 2010-08-02 09:36:27.503133517 +0200
+++ Makefile 2010-08-02 23:00:33.000000000 +0200
@@ -0,0 +1,20 @@
+.POSIX:
+
+CXXFLAGS = -ansi -pedantic -Wall -Wextra -Wformat=2
+
+default: app lib.so
+
+app: app.o
+ g++ -o app -rdynamic app.o -l dl
+
+lib.so: lib.o
+ g++ -shared -o lib.so -fPIC lib.o
+
+app.o: app.cpp app.h
+ g++ $(CXXFLAGS) -c -o app.o app.cpp
+
+lib.o: lib.cpp app.h
+ g++ $(CXXFLAGS) -fPIC -c -o lib.o lib.cpp
+
+clean:
+ rm -f app app.o lib.so lib.o
From: DeMarcus on
On 2010-08-03 00:25, Ersek, Laszlo wrote:
> On Mon, 2 Aug 2010, DeMarcus wrote:
>
>> I have a program written in C++ with global variables. Now I want to
>> make those global variables available to shared libraries linked in to
>> the software.
>>
>> I've compiled with g++ 4.5.0 using -rdynamic but when I load the
>> library with dlopen() i get the error message: "undefined symbol:
>> __dso_handle".
>>
>> Doing nm MyApp | grep __dso_handle gives me
>> 000000085a438 d __dso_handle which means __dso_handle is internal.
>>
>> What am I doing wrong? Is there a good tutorial for linking C++ code
>> dynamically?
>
> The following works for me on Debian Lenny.
>
> Cheers,
> lacos
>
> --- /dev/null 2010-08-02 09:36:27.503133517 +0200
> +++ app.h 2010-08-02 23:44:25.000000000 +0200
> @@ -0,0 +1,10 @@
> +class My
> +{
> + int i;
> +
> + public:
> + void set(int i);
> + int get();
> +};
> +
> +extern My my;
> --- /dev/null 2010-08-02 09:36:27.503133517 +0200
> +++ lib.cpp 2010-08-03 00:03:47.000000000 +0200
> @@ -0,0 +1,11 @@
> +#define _XOPEN_SOURCE 600
> +
> +#include "app.h"
> +
> +extern "C" void foo();
> +
> +void
> +foo()
> +{
> + my.set(1);
> +}
> --- /dev/null 2010-08-02 09:36:27.503133517 +0200
> +++ app.cpp 2010-08-03 00:19:51.000000000 +0200
> @@ -0,0 +1,68 @@
> +#define _XOPEN_SOURCE 600
> +
> +#include <dlfcn.h> /* dlopen() */
> +#include <stdio.h> /* fprintf() */
> +#include <stdlib.h> /* EXIT_FAILURE */
> +#include <errno.h> /* errno */
> +#include <string.h> /* strerror() */
> +
> +#include "app.h"
> +
> +
> +void
> +My::set(int i)
> +{
> + this->i = i;
> +}
> +
> +int
> +My::get()
> +{
> + return this->i;
> +}
> +
> +
> +My my;
> +
> +extern "C" typedef void foofun_type(); /* See C++03 7.5 p4. */
> +
> +int
> +main()
> +{
> + int ret;
> + void *handle;
> +
> + ret = EXIT_FAILURE;
> +
> + handle = dlopen("./lib.so", RTLD_NOW | RTLD_LOCAL);
> + if (0 == handle) {
> + (void)fprintf(stderr, "dlopen(): %s\n", dlerror());
> + }
> + else {
> + void *sym;
> +
> + sym = dlsym(handle, "foo");
> + if (0 == sym) {
> + (void)fprintf(stderr, "dlsym(): %s\n", dlerror());
> + }
> + else {
> + foofun_type *foofun; /* pointer to C function */
> +
> + *(void **)&foofun = sym;
> + (*foofun)();
> + if (0 > fprintf(stdout, "%d\n", my.get()) || EOF == fflush(stdout)) {
> + (void)fprintf(stderr, "fprintf()/fflush(): %s\n", strerror(errno));
> + }
> + else {
> + ret = EXIT_SUCCESS;
> + }
> + }
> +
> + if (0 != dlclose(handle)) {
> + (void)fprintf(stderr, "dlclose(): %s\n", dlerror());
> + ret = EXIT_FAILURE;
> + }
> + }
> +
> + return ret;
> +}
> --- /dev/null 2010-08-02 09:36:27.503133517 +0200
> +++ Makefile 2010-08-02 23:00:33.000000000 +0200
> @@ -0,0 +1,20 @@
> +.POSIX:
> +
> +CXXFLAGS = -ansi -pedantic -Wall -Wextra -Wformat=2
> +
> +default: app lib.so
> +
> +app: app.o
> + g++ -o app -rdynamic app.o -l dl
> +
> +lib.so: lib.o
> + g++ -shared -o lib.so -fPIC lib.o
> +
> +app.o: app.cpp app.h
> + g++ $(CXXFLAGS) -c -o app.o app.cpp
> +
> +lib.o: lib.cpp app.h
> + g++ $(CXXFLAGS) -fPIC -c -o lib.o lib.cpp
> +
> +clean:
> + rm -f app app.o lib.so lib.o

Thanks! I'll try your example.