Stringet mint function futtatni lehet?

 ( vargadanis | 2008. április 26., szombat - 20:01 )

Hi!

Azt szeretném tudni, hogy egy charsorozatot lehet-e, mint function kezelni.. PL:

#include <stdio.h>
#include <string.h>

void execExit()
{
        printf("Test worked");
}

int main(int argc, char* argv[])
{
	struct cmd
	{
		char name[16];
		unsigned short privilegeLevel;
		unsigned short menuLevel;
		char executeFunction[32];
	};
	typedef struct cmd cmd_t;
	cmd_t cmdExit = { "exit", 0, 0, "execExit"};
        //Ide kellene valami ami az cmdExit.executeFunction-nel kezd vmit	
	char c = getch();
	return 0;
}

OS: Linux, GCC:3.2

Köszi

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Esetleg char* - function pointer parossal egy struct-ba rakva.
Letarolod a nevekkel a fuggvenyeket, es meghivod a hozzatartozo fv-t.

En igy oldanam meg. Ha C++ akkor lehet valami standard taroloba is pakolni oket.

struct lookup_table {
char id[32];
void (*function) (void);
};

Remelem ertheto igy kivonatosan. +1 kereso fuggveny, ami megnezi melyik id-hez melyik function tartozik.

Ha pluginek nincsenek akkor valoszinuleg a fuggvenyek sem valtoznak, tehet (string)nev helyett lehetne enum vagy #define al definialni valami szepet.
(gyorsabb kisebb)

Ha minden aron neve alapjan akarod keresni oket:
Forditashoz -rdynamic

program indulasakor:
void * handle=dlopen(NULL,RTLD_LAZY);

szimbolum megszerzese:
void (*function) (void);
function=dlsym(handle, "execExit");

!NULL figyelni.

áááááá
system("PAUSE"); nevű rendszerhívást tessék már elfelejteni! miért nem jó egy getch() helyette? miért kell egy karakter bekéréséért rendszerhívást csinálni?

Igenis!! SYSTEM CALL elfelejtve :)
SDN megnézem ez h néz ki a gyakorlatban... azért még ha vkinek van 5lete szívesen várom :)

system nem rendszer hivast jelent.
getch is csinal rendszer hivast (read).
man syscalls
man syscall

Attol meg a system("PAUSE") rossz.

Legyszi [code] [/code] koze tedd a fenti kodot (szerkesztes), igy eltorik a szemem.

Felmegoldast talaltam. Csak akkor mukodik, ha a fuggveny amit hivni akarsz, shared objectben van.

dl.c:

#include <dlfcn.h>
#include <stdio.h>

void f(void);
void g(void){}

int main(int argc, char * argv[])
{
        void * handle;
        handle = dlopen(NULL, RTLD_LAZY);
        if (!handle) {
                fprintf(stderr, "%s\n", dlerror());
                return 2;
        }
        for (int i = 1; i < argc; i++) {
                char const * e = dlerror();
                dlsym(handle, argv[i]);
                e = dlerror();
                if (e)
                        printf("%s: %s.\n", argv[i], e);
                else
                        printf("%s found.\n", argv[i]);
        }
        if (dlclose(handle)) {
                fprintf(stderr, "%s\n", dlerror());
                return 3;
        }
        return 0;
}

dl_f.c:

void f(void){}

$ c99 -c dl_f.c && ld -shared dl_f.o -o dl_f.so
$ c99 dl.c dl_f.so -ldl -o dl
$ LD_LIBRARY_PATH=. ./dl main f printf
main: ./dl: undefined symbol: main.
f found.
printf found.

"Csak akkor mukodik, ha a fuggveny amit hivni akarsz, shared objectben van."
-rdynamic -el forgatva ?

szerk:
g++ dl.c -ldl -rdynamic
./a.out main
main found.

C++-hoz nincs valami olyasmi, mint java-ban a reflection?

Reflection managed környezetekben játszik.

A C forditott nyelv, nem interpretalt. Szoval nincs eval.
Ahogy fent mar irtak, futasidoben betoltheto leforditott shared lib. Ha telepitve van fordito, akkor futas kozben le tudod forditani, es be tudod tolteni, de nem illik ilyet tenni (ennek ellenere pl. az LPC igy mukodik).
Ha erre van szukseged, valoszinuleg rosszul tervezted meg a programodat vagy rosszul valasztottal nyelvet.

----
Sooner or later you had to talk, even if it was only because you'd run out of things to throw. - Pratchett
honlap készítés

Az meglehet... Mindenesetre köszi srácok a 5leteket belenézek ebbe a pointeresdibe a functionökre és ha kiötlök valami tutit, akkor azért bepötyögöm ide...

Le tudod irni, hogy pontosan mi a feladat?

----
Sooner or later you had to talk, even if it was only because you'd run out of things to throw. - Pratchett
honlap készítés

Persze, hogy meg lehet oldani.
Function-pointerekkel.
Kell csinálnod egy listát, melyben el vannak tárolva a funtion-ok nevei, illetve egy, a functionra mutató pointer.
Atán kell írnod egy eljárást, ami a string-ként megadott nevet megkeresi a listában, és meghívja a hozzá tartozó function-t.

Asszem egyikunk felreertette a kerdest (nem kizart, hogy en).
Ertelmezesem szerint az a feladat, hogy futasidoben forduljon/ertekelodjon ki a fuggveny (mint a javascript eval() ).

----
Sooner or later you had to talk, even if it was only because you'd run out of things to throw. - Pratchett
honlap készítés

Azt hiszem te erteted felre.
A kerdes abbol fakadhatott, hogy a kerdezo nem sok fuggvenyre mutato pointert hasznalt/latott meg.

Ez egy jó meglátás... sőt tuti h még egyet sem, de most belehúz (belehúzok)

Itt van egy pl kód, ami szépten működik:

#include <stdio.h>
#include <string.h>

int execExit()
{
	printf("Test worked");
        return 1;
}

int main(int argc, char* argv[])
{
	char t[]="Help";
	struct cmd
	{
		char name[16];
		unsigned short privilegeLevel;
		unsigned short menuLevel;
		int (*executeFunction)();		
	};
	typedef struct cmd cmd_t;
	cmd_t cmdExit;	
	cmdExit.executeFunction = execExit;
	printf("%d", cmdExit.executeFunction());
	char c = getchar();
	return 0;
}

köszi a segítséget mégegyszer srácok

Elvileg semmi akadálya annak, hogy ezt írd:

cmd_t cmdExit = { "exit", 0, 0, execExit};

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o