473,473 Members | 1,535 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

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 4647
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: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.