Funktionszeiger in array - aber anders!

zoidberger

Mitglied
Hallo Leute!
Da meine letzte Frage wohl zu kompliziert gestellt wurde, frag ich heute mal wieder einfacher ;)

Ich will funktionszeiger in ein array schmeißen und diese an geeigneter stelle aus dem arrray lesen und die zugehörigen funktionen ausführen.
Ich habe viele Beispiele im Netz gefunden wie das geht, allerdings brauch ich einen sonderfall.. in dem array sollen auch noch andere sachen stehen.
Genauer genommen könnte man das array als tabelle bezeichnen.
und in der hintersten spalte sollte eben der funktionszeiger stehen.

Also ich mach es nicht:
Code:
typedef void (*pFunc)();
void Func1()
{
    //...
}
void Func2()
{    
    //...
}
int main()
{
    pFunc Arr[2];
    Arr[0] = &Func1;
    Arr[1] = &Func2;
    int i;
    for (i = 0; i < 2 ; i++)
    {
       Arr[i]();
    }
    return 0;
}

sondern meine funktionszeiger stehen in einem beliebigen array an, das nichts mit dem funktionszeiger selbst zu tun hat..

geht das überhaupt?
Mit cvi geht das scheinbar ;)
 
Hi

so ein ähnliches Thema hab ich etztens schonmal gelesen, hab es aber nicht mehr wieder gefunden.

Du könntest für dein Array eine Struktur/Union erstellen. Da speichert du dann deine Funk.-Ptr. oder die anderen Daten. Zusätzlich mit ner Status-Var., die angibt, was sich jetzt wirklich in der Union befindet.

Bsp:
Code:
struct array_struct {
  int type;
  union {
       pFunc funcPtr;
       int iv;
       float fv;
  } data;
};

lg
 
Okay..
Also im Moment hab ich ein struct so definiert:

Code:
	typedef struct { 
		char 	tag[MAX_LEN_TAG];                 // Tag-Name  
		TAG_IDENTIFYER_TYP tag_id;	     
		TAG_VALUE_TYPE	    tag_valtype;     // Type des zum Tag gehörenden Wertes
		int	(*pFunc)(int nTagIndex, TAG_PARSE_RESULT_TYPE *pPduCmd); //fp
	}TAG_DESCR_TYPE;

also habe ich in dem struct den Funktionszeiger namens *pFunc angelegt.
Das Array sieht dann folgendermaßen aus:

Code:
TAG_DESCR_TYPE g_DecodeTableInit[MAXLEN_DECODE_CONTROL_TABLE] =	
	{ 		
	//  tag        tag_id                    Value type                  funktion-	    
	// 			  				                       pointer
	// -------------------------------------------------------------------------------------------------
	{"#",         COMMENT_TAG,    TAGVAL_STRING,       pruefComment}, 
	{"exit",      EXIT_TAG,              TAGVAL_STRING,      ExitFunc},
        ...}

Leider erhalte ich beim builden einen C2440 Fehler ('initializing' : cannot convert from 'overloaded-function' to 'int(__cdecl*)(int,TAG_PARSE_RESULT_TYPE*)'

Auch die Erklärung http://msdn2.microsoft.com/de-de/library/sy5tsf8z(VS.80).aspx
bringt keine Lösung mit sich..

Ich bin gerade am überlegen ob ich nicht einfach 2 arrays machen soll.. das 2. Array dann einfach nur für die funktionszeiger..

Aber das ist ja auch wieder rumgepfuscht..
 
Hi

ohne die MSDN-Seite gelesen zuhaben, dein Code kann so nicht funktionieren.

Denn mit
Code:
int array[3] = { 1,2,3};
geht das nur bei einfachen Datentypen.

Du musst dein Array mit der Struktur Element für Element einzeln zuweisen.

lg
 
@higret

Ich bin mir da aber ganz sicher, dass man ein array mit komplexen datentypen bei der initialisierung auch so anlegen kann. Der gleiche Code (leicht abgeändert) fünktioniert bei CVI einwandfrei.
Andererseits weiß ich im Moment auch nicht weiter.. ich werde mal versuchen (testweise) ein paar zeilen einzeln zu initialisieren..

danke schonmal für die Antworten!
 
Hi

stimmt, habs grad mal mit ner Test-Struct ausprobiert. Ein Array davon kann man, so wie du geschrieben hast initialisieren, auch mit nem Funk.-Ptr. drin geht das.
 
Aber wieso mag er das dann bei mir nicht... ?
Soll ich dir mal einen größeren teil des codes oder gar alles schicken?
 
Das komische ist grad, wenn ich das selbe nicht objektorrientiert versuche, also alles in eine cpp file reinklatsch, nimmt er es ohne probleme...
sobald ich dann wieder ne klasse draus mach, geht garnichtsmehr!

Ich hab jetzt grad sogar dem Array alle Werte einzeln zugewiesen!

Hier mein Code:

tagtabelle_ohne_klassen.cpp (ja ich weiß jetzt doch mit klassen ;) )

Code:
#include "stdafx.h"

using namespace std;

int k = 5;
int* lalala = &k;

int tagTab::pruefComment(int nTagIdx, void *pPduCmd){
	if ( g_DecodeTableInit[0].tag_id == 74 ){
		cout << "test erfolgreich" << endl;
	}
	return 0;
}
	
int tagTab::ExitFunc(int nTagIdx, void *pPduCmd){
	return 0;
}
	
tagTab::tagTab(){

	strcpy("#", g_DecodeTableInit[0].tag);
	g_DecodeTableInit[0].tag_id = 74;
	g_DecodeTableInit[0].tag_valtype = 1;
	g_DecodeTableInit[0].pFunc = pruefComment;
	
	strcpy("exit", g_DecodeTableInit[1].tag);
	g_DecodeTableInit[1].tag_id = 34;
	g_DecodeTableInit[1].tag_valtype = 2;
	g_DecodeTableInit[1].pFunc = ExitFunc;
	
}

int main()
{
	tagTab tagTabTest;
	tagTabTest.pruefComment(0, lalala);
}

tagtabelle_ohne_klassen.h

Code:
#include "stdafx.h"
using namespace std;



class tagTab{

public:

typedef struct { 
    char tag[100]; // Tag-Name 
    int tag_id; // programminterne Konstante
    int tag_valtype; // Type des zum Tag gehörenden Wertes
    int (*pFunc)(int nTagIndex, void *pPduCmd); //Funktionszeiger
}TAG_DESCR_TYPE;

	tagTab();
	int pruefComment(int nTagIdx, void *pPduCmd);	
	int ExitFunc(int nTagIdx, void *pPduCmd);

private:
	TAG_DESCR_TYPE g_DecodeTableInit[10];


};

und in der stdafx.h:

Code:
#pragma once


#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <tchar.h>
#include <cmath>
#include <iostream>
#include <conio.h>
#include <exception>
#include "tagtabelle_ohne_klassen.h"

und damit hat er schonwieder probleme...
 
Ok, Fehler gefunden.

Pointer auf Methoden und Pointer auf Funktionen sind unterschiedlich.
Denn eine Methode ist ja Objekt gebunden und da muss halt zusätzlich zu der Adresse der Methode noch die Adresse des Objekts (also this) mit gespeichert werden.

Wenn du den Funktionspointer auf

Code:
int (tagTab::*pFunc)(int nTagIndex, void *pPduCmd);

änderst sollte es gehen.

Zum Nachlesen
http://tutorial.schornboeck.net/meth_zeiger.htm

lg
 
Zurück