подскажите ("ломаю" голову не один день (( )string namefunc("thisfunc");
string nameobj("thisobj");1. как вызвать функцию, имя которой содержится в namefunc?
2. как вызвать функцию объекта (вообще получить доступ к нему), имя которого в nameobjблагодарствую
man dlopen(3), dlsym(3)
>man dlopen(3), dlsym(3)
а попроще нельзя, подымать такую махину ради (вроде бы) простого действия
в перлах ведь можно написать $$namevar, может какой-нить подобный трюк с с++ есть?
>>man dlopen(3), dlsym(3)
>
>
>а попроще нельзя, подымать такую махину ради (вроде бы) простого действия
>в перлах ведь можно написать $$namevar, может какой-нить подобный трюк с с++
>есть?
Это вообще говоря не забота конкретного языка , будь-то C или C++.
под Unix тебе уже отсоветовали.
по Win32 то же самое делает LoadLibraryEx
>>>man dlopen(3), dlsym(3)
>>
>>
>>а попроще нельзя, подымать такую махину ради (вроде бы) простого действия
>>в перлах ведь можно написать $$namevar, может какой-нить подобный трюк с с++
>>есть?
>
>
>Это вообще говоря не забота конкретного языка , будь-то C или C++.
>
>под Unix тебе уже отсоветовали.
>по Win32 то же самое делает LoadLibraryEx
ну зачем мне подгружать отдельную библиотеку, если функция или объект
находятся "рядом"?просто в зависимости от условий, имя вызываемой ф-ии или объекта находятся в
строковой переменной.
>>>>man dlopen(3), dlsym(3)
>>>
да это не годиться! в условиях задачи нет нифига использования динамически загружаемых библиотек, а значит и использовать этот специфический механизм нельзя. тем более им невозможно работать с объектами.Решаетмя это на уровне метаобъектов, при котором создаются таблицы соответствия имен и функций, и объектов и их имен. Честно говоря не представляю зачем это нужно.
Поскольку нужно будет еще динамически узнавать набор переменных передаваемых в функцию, а для объктов их тип, динамических кастов будет мама не горюй, и отладить такой механизм будет очень затруднительно. В итоге мы получим просто еще один интерпретируемый язык.
На мой взгляд, здесь просто ошибка в проектировании.
>Решаетмя это на уровне метаобъектов, при котором создаются таблицы соответствия имен и
>функций, и объектов и их имен. Честно говоря не представляю зачем
>это нужно.
>Поскольку нужно будет еще динамически узнавать набор переменных передаваемых в функцию, а
>для объктов их тип, динамических кастов будет мама не горюй, и
>отладить такой механизм будет очень затруднительно. В итоге мы получим просто
>еще один интерпретируемый язык.
>На мой взгляд, здесь просто ошибка в проектировании.не, список параметров/членов_объектов будет одинаковый
может кто-нибудь покажет как вызвать функцию по имени из переменной (
>
>>Решаетмя это на уровне метаобъектов, при котором создаются таблицы соответствия имен и
>>функций, и объектов и их имен. Честно говоря не представляю зачем
>>это нужно.
>>Поскольку нужно будет еще динамически узнавать набор переменных передаваемых в функцию, а
>>для объктов их тип, динамических кастов будет мама не горюй, и
>>отладить такой механизм будет очень затруднительно. В итоге мы получим просто
>>еще один интерпретируемый язык.
>>На мой взгляд, здесь просто ошибка в проектировании.
>
>не, список параметров/членов_объектов будет одинаковый
>
>может кто-нибудь покажет как вызвать функцию по имени из переменной (dlopen() на самого себя и вперед :)
>может кто-нибудь покажет как вызвать функцию по имени из переменной (
смотри, это просто вызов функции из переменной:
#include <iostream>
#include <string>typedef int (*func)(int x, int y);
int sum(int x, int y) {
return x + y;
}
int main(int argc, char* argv[]) {
func f;f = sum;
int s = f(1, 2);
std::cout << "Rezult is: " << s << std::endl;
return 0;}
А вот что может быть если добавить map:
#include <map>
#include <iostream>
#include <string>using namespace std;
typedef int (*func)(int x, int y);
typedef map< string, func, less <string> > named_func_map;class named_func {
private:
named_func_map nfm;
public:
void insert(string s, func f);
int run(string s, int v1, int v2);
};
void named_func::insert(string s, func f){
nfm.insert(make_pair(s, f));
}int named_func::run(string s, int v1, int v2) {
func f;
int ret = 0;
if(nfm.find(s) != nfm.end()) {
f = nfm[s];
ret = f(v1, v2);
}
return ret;
}int sum(int x, int y) {
return x + y;
}int sub(int x, int y) {
return x - y;
}
int main(int argc, char* argv[]) {
func f;
named_func nf;
nf.insert("sum", sum);
nf.insert("sub", sub);
cout << "Initialize succesful!" << endl;
//int s = f(1, 2);
std::cout << "Rezult sub 15 - 7 is: " << nf.run("sub", 15, 7) << std::endl;
std::cout << "Rezult sum 15 + 7 is: " << nf.run("sum", 15, 7) << std::endl;
return 0;}
dlopen с первым параметром NULL откроет для тебя глобальную таблицу.
>dlopen с первым параметром NULL откроет для тебя глобальную таблицу.в принципе можно сделать и через dlopen вот код, только он не работает ;-)) и там поясненно почему:
/*
НЕ РАБОТАЕТ!!!!
что бы так работало надо функции
sum и sub вынести в отдельный файл
func.c
скомплировать его как разделяемую библиотеку
gcc -c -fPIC -o func.o func.c
gcc -shared -fPIC -o libfunc func.o
а затем уже подсоединить при линковке эту библиотеку(если влом загружать ее динамически)
gcc -o call_func_dlopen call_func_dlopen.c -L. -lfunc
вот тогда, должно заработать ;-))
*/#include <map>
#include <iostream>
#include <string>
#include <dlfcn.h>using namespace std;
typedef int (*func)(int x, int y);
typedef map< string, func, less <string> > named_func_map;class named_func {
private:
static void *libself;
static int count_use;
named_func_map nfm;
public:
named_func();
~named_func();
//void insert(string s, func f);
int run(string s, int v1, int v2);
};void *named_func::libself = NULL;
int named_func::count_use = 0;
named_func::named_func() {
if(libself == NULL) {
libself = dlopen(NULL, RTLD_LAZY);
//libself = dlopen(NULL, RTLD_GLOBAL);
if (!libself) {
cerr << "Can't load symbols, " << dlerror() <<endl;
} else {
count_use++;
}
} else {
count_use++;
}
}named_func::~named_func() {
if(libself != NULL) {
count_use--;
if(count_use <= 0) {
int res = dlclose(libself);
libself = NULL;
if(res != 0) {
cerr << "Error close selflib, " << res << endl;
}
}
}
}
int named_func::run(string s, int v1, int v2) {
func f;
int ret = 0;
void *rez = 0;
char *error;
if(libself == NULL) {
cerr << "Can't run " << s << ", library is not initialized!" << endl;
}
rez = dlsym(libself, s.c_str());
if ((error = dlerror()) != NULL) {
cerr << error << endl;
} else {
f = (func)rez;
ret = f(v1, v2);
}
return ret;
}int sum(int x, int y) {
return x + y;
}int sub(int x, int y) {
return x - y;
}
int main(int argc, char* argv[]) {
func f;
named_func nf;
//nf.insert("sum", sum);
//nf.insert("sub", sub);
cout << "Initialize succesful!" << endl;
//int s = f(1, 2);
std::cout << "Rezult sub 15 - 7 is: " << nf.run("sub", 15, 7) << std::endl;
std::cout << "Rezult sum 15 + 7 is: " << nf.run("sum", 15, 7) << std::endl;
return 0;}
>>dlopen с первым параметром NULL откроет для тебя глобальную таблицу.>#include <map>
а блин, забыл убрать, ну кому надо уберет. ;-), здесь оно уже не надо.
>>>dlopen с первым параметром NULL откроет для тебя глобальную таблицу.
>
>>#include <map>
>а блин, забыл убрать, ну кому надо уберет. ;-), здесь оно уже
>не надо.
нужно!
спасибо за помощь!если есть ещё соображения, как добраться до объекта, имя которого
содержится в строковой переменной... плз поделитесь