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 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 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!" 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.
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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...
|
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...
|
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
|
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...
|
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...
| |
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...
|
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))...
|
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...
|
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,...
|
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...
|
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,...
| |
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...
|
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,...
|
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...
|
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...
|
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...
|
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 ...
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |