473,249 Members | 1,876 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,249 software developers and data experts.

dlsym and function pointer ...

Hello All,

I am a newbie to C++. I was trying a sample program from internet which
demonstrates dynamic class loading in C++. Actually, I thought of using
this design, in one of the applications I am working on.

However, the compilation was through. But when ran, the program
generated a SIGSEGV error. I debugged it using gdb and found that ,when
the symbol returned by dlsym() was invoked, the resulting value was
null.

I couldn't understand clearly why it didn't worked. The problematic
location in the code
has been denoted below(calc.cpp):

calc.cpp:

#include "calculator.hpp"
typedef Math* (*factory)(void);

bool Calculator::load(char* library_name) {

factory make;

/* Open shared library */
handle = dlopen(library_name, RTLD_NOW);
if (!handle) {
cout << dlerror();
return false;
}

/* Load symbols from library */
make = (factory)dlsym(handle, "maker");
if (make = NULL) {
cout << dlerror() << "\n";
return false;
}

/* Construct object */
math = (*make)(); ===> *** This is Problem location***

cout << (void*)math << "\n";

return true;

}

bool Calculator::calculate() {

float a;
cout << "Enter float:\n";
fscanf(stdin,"%f",&a);

c = math->square(a);

cout << "Square: " << c << '\n";
return true;
}

bool Calculator::close() {
char *error;

dlerror();
dlclose(handle);
if ((error = dlerror()) != NULL) {
cout << error;
return false;
}
return true;
}

main.cpp:

#include "calculator.hpp"

int main (int argc, char* argv[]) {

if (argc != 2)
cout << "Usage: calc \n";

Calculator* c = new Calculator();

if (c->load(argv[1])) {
c->calculate();
c->close();
}

delete c;
return 0;
}

calculator.hpp:

#ifndef __CALCULATOR_H
#define __CALCULATOR_H

#include "math.hpp"

class Calculator {
public:
bool load(char* library);
bool calculate();
bool close();
private:
void* handle;
Math* math;
};

#endif

math.hpp:

#ifndef __MATH_H
#define __MATH_H

class Math {
public:
virtual float multiply(float a, float b);
virtual float square(float a);
};

#endif

math.cpp:

#include "math.hpp"

float Math::multiply(float a, float b) {
return a*b;
}

float Math::square(float a) {
return a*a;
}

extern "C" {
Math *maker() {
return new Math;
}
}
I'm using g++ 3.2.3 and below is the makefile used to compile the
program.

LIB_SRC = math.cpp
LIB_OBJ = math.o
LIB = math

BIN_SRC = main.cpp calc.cpp
BIN = calc

LIB_VER_MAJOR =
LIB_VER_MINOR =

CC = g++
LIB_OBJ_FLAGS = -fPIC -c -Wall -g
LIB_SO_FLAGS = -shared -lc -Wl,-soname
BIN_FLAGS = -rdynamic -ldl -Wall -g

all: lib.o lib.so bin

lib.o:
$(CC) $(LIB_OBJ_FLAGS) $(LIB_SRC)

lib.so:
$(CC) $(LIB_SO_FLAGS),$(LIB).so.$(LIB_VER_MAJOR) \
-o $(LIB).so$(LIB_VER_MAJOR)$(LIB_VER_MINOR) $(LIB_OBJ)

bin:
$(CC) $(BIN_FLAGS) -o $(BIN) $(BIN_SRC)

clean:
rm -f *.o *.so* $(BIN)
Any pointers/suggestions to solve this problem will be really
appreciated. The argument to calc exe is math.so

Thanks & Regards,

Karthik D

Dec 13 '05 #1
4 4633
dkart...@gmail.com wrote:
Hello All,

I am a newbie to C++. I was trying a sample program from internet which
demonstrates dynamic class loading in C++. Actually, I thought of using
this design, in one of the applications I am working on.

However, the compilation was through. But when ran, the program
generated a SIGSEGV error. I debugged it using gdb and found that ,when
the symbol returned by dlsym() was invoked, the resulting value was
null.

I couldn't understand clearly why it didn't worked. The problematic
location in the code
has been denoted below(calc.cpp):

calc.cpp:

#include "calculator.hpp"
typedef Math* (*factory)(void);

bool Calculator::load(char* library_name) {

factory make;

/* Open shared library */
handle = dlopen(library_name, RTLD_NOW);
if (!handle) {
cout << dlerror();
return false;
}

/* Load symbols from library */
make = (factory)dlsym(handle, "maker");
if (make = NULL) {
cout << dlerror() << "\n";
return false;
}

/* Construct object */
math = (*make)(); ===> *** This is Problem location***

cout << (void*)math << "\n";

return true;

}

bool Calculator::calculate() {

float a;
cout << "Enter float:\n";
fscanf(stdin,"%f",&a);

c = math->square(a);

cout << "Square: " << c << '\n";
return true;
}

bool Calculator::close() {
char *error;

dlerror();
dlclose(handle);
if ((error = dlerror()) != NULL) {
cout << error;
return false;
}
return true;
}

main.cpp:

#include "calculator.hpp"

int main (int argc, char* argv[]) {

if (argc != 2)
cout << "Usage: calc \n";

Calculator* c = new Calculator();

if (c->load(argv[1])) {
c->calculate();
c->close();
}

delete c;
return 0;
}

calculator.hpp:

#ifndef __CALCULATOR_H
#define __CALCULATOR_H

#include "math.hpp"

class Calculator {
public:
bool load(char* library);
bool calculate();
bool close();
private:
void* handle;
Math* math;
};

#endif

math.hpp:

#ifndef __MATH_H
#define __MATH_H

class Math {
public:
virtual float multiply(float a, float b);
virtual float square(float a);
};

#endif

math.cpp:

#include "math.hpp"

float Math::multiply(float a, float b) {
return a*b;
}

float Math::square(float a) {
return a*a;
}

extern "C" {
Math *maker() {
return new Math;
}
}
I'm using g++ 3.2.3 and below is the makefile used to compile the
program.

LIB_SRC = math.cpp
LIB_OBJ = math.o
LIB = math

BIN_SRC = main.cpp calc.cpp
BIN = calc

LIB_VER_MAJOR =
LIB_VER_MINOR =

CC = g++
LIB_OBJ_FLAGS = -fPIC -c -Wall -g
LIB_SO_FLAGS = -shared -lc -Wl,-soname
BIN_FLAGS = -rdynamic -ldl -Wall -g

all: lib.o lib.so bin

lib.o:
$(CC) $(LIB_OBJ_FLAGS) $(LIB_SRC)

lib.so:
$(CC) $(LIB_SO_FLAGS),$(LIB).so.$(LIB_VER_MAJOR) \
-o $(LIB).so$(LIB_VER_MAJOR)$(LIB_VER_MINOR) $(LIB_OBJ)

bin:
$(CC) $(BIN_FLAGS) -o $(BIN) $(BIN_SRC)

clean:
rm -f *.o *.so* $(BIN)
Any pointers/suggestions to solve this problem will be really
appreciated. The argument to calc exe is math.so

Thanks & Regards,

Karthik D


Greetings and welcome to comp.lang.c++. Unfortunately, because dlsym()
is not a standard library function, this question is outside the scope
of this newsgroup, which is intended for discussions of the language
itself rather than third-party library or platform-specific questions.
I'd suggest you post in a newsgroup for your platform or compiler. See
the FAQ for some suggestions of where to post:

http://www.parashift.com/c++-faq-lit...t.html#faq-5.9

Cheers! --M

Dec 13 '05 #2
dk******@gmail.com wrote:
Hello All,

I am a newbie to C++. I was trying a sample program from internet which
demonstrates dynamic class loading in C++. Actually, I thought of using
this design, in one of the applications I am working on.

However, the compilation was through. But when ran, the program
generated a SIGSEGV error. I debugged it using gdb and found that ,when
the symbol returned by dlsym() was invoked, the resulting value was
null.
Though dlsym() is not part of standard C++ (and therefore off topic) you
have a rather different problem in your code -- of the `Doh!' variety.

See below. You've been thinking too hard. ;-)
I couldn't understand clearly why it didn't worked. The problematic
location in the code
has been denoted below(calc.cpp):

calc.cpp:

#include "calculator.hpp"
typedef Math* (*factory)(void);

bool Calculator::load(char* library_name) {

factory make;

/* Open shared library */
handle = dlopen(library_name, RTLD_NOW);
if (!handle) {
cout << dlerror();
return false;
}

/* Load symbols from library */
make = (factory)dlsym(handle, "maker");
if (make = NULL) {
No matter *what* dlsym() returned, you just set it to NULL in the above
line!!!! [Hint: *Turn up the warning level on your compile*!!]
cout << dlerror() << "\n";
return false;
}

/* Construct object */
math = (*make)(); ===> *** This is Problem location***


Well, no it's not. See above.

[snip]

HTH,
--ag
--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com (new post 8/5)
http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"
Dec 13 '05 #3
dk******@gmail.com wrote:
....
Any pointers/suggestions to solve this problem will be really
appreciated. The argument to calc exe is math.so


Don't use dlsym. Look at somthing like Austria C++ generic factories.
It is a standard C++ way of doing the same thing. No need to use extern
"C".

The documentation has alot to be desired.
http://austria.sourceforge.net/dox/h...Factories.html

Basically, you define an interface class.

class MakerIF
{
public:
virtual void f() = 0;
};

Then in the file that makes the shared object (.so or .dll file).

----------------- impl.cpp -------------------------
#include "at_factory.h"
#include "app_interface.h"
class MakerImpl
: public MakerIF
{
public:
virtual void f()
{
Stuff();
}
};

// Register the factory
AT_MakeFactory0P( "NameOfImpl", MakerIF, MakerImpl, at::DKy );
----------------------------------------------------

------------------ main app code -------------------
#include "at_factory.h"
#include "app_interface.h"

int main()
{

void * dlhnd = dlopen( "impl.so" );

MakerIF * obj = at::FactoryRegister< MakerIF >
::Get().Create( "NameOfImpl" )();

if ( obj )
{
obj->f();
}
}
-----------------------------------------------------

Admitedly, it's been a while since I tested using dlopen(), but it
should be no issue. You will need to use Austria C++ as a .so/dll to
make this work or there needs to be exactly one place where the
FactoryRegisterRegistry::Get() function gets installed, otherwise it
won't work with multiple factory registries.
Dec 13 '05 #4
Hi Ag,

Thanks for pointing it out. It didn't striked me. Once I modified that,
it worked fine. Once again thanks.
Thanks & Regards,

Karthik D

Dec 14 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
37
by: Ben | last post by:
Hi, there. Recently I was working on a problem where we want to save generic closures in a data structure (a vector). The closure should work for any data type and any method with pre-defined...
2
by: sushil | last post by:
+1 #include<stdio.h> +2 #include <stdlib.h> +3 typedef struct +4 { +5 unsigned int PID; +6 unsigned int CID; +7 } T_ID; +8 +9 typedef unsigned int (*T_HANDLER)(void); +10
7
by: Mike D. | last post by:
I have a problem with a dynamic library I am developing, but it is really more of a pointer issue than anything else. Hopefully someone here can lend me some assistance or insight into resolving...
27
by: Marlene Stebbins | last post by:
I am experimenting with function pointers. Unfortunately, my C book has nothing on function pointers as function parameters. I want to pass a pointer to ff() to f() with the result that f() prints...
23
by: bluejack | last post by:
Ahoy... before I go off scouring particular platforms for specialized answers, I thought I would see if there is a portable C answer to this question: I want a function pointer that, when...
0
by: nirnimesh | last post by:
I'm intercepting a library function call using LD_PRELOAD and in-turn calling the orignial library function. Essentially, intercept.cc: void (*real_func)(void) = (void (*) (void))...
10
by: Richard Heathfield | last post by:
Stephen Sprunk said: <snip> Almost. A function name *is* a pointer-to-function. You can do two things with it - copy it (assign its value to an object of function pointer type, with a...
6
by: tvnaidu | last post by:
opening shared lib with dlopen, gets success, but dlsym returns an error saying undefined symbol, also passing "-rdynamic" during linking this shared lib, any idea?. dlopen success, dlsym gets error,...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.