Problem bei Funktionszeiger!

pat-

Grünschnabel
Hallo tutorial'ianer!

Ich habe eine Klasse Cmd, in der ich Kommandos erzeuge. Ein Attribut der Klasse ist als Funktionszeiger implementiert. Dieser Funktionszeiger soll auf die für den Kommando vorgesehende Funktion zugewiesen werden. In meinem Fall übergebe ich einem Objekt der klasse Cmd eine Funktion der Klasse Flash_cmd(diesse Klasse besitzt Funktionen zur Ansteuerung eines Flashspeichers). Die Klasse Flash-Cmds ist als Singleton-pattern implementiert und die Übergabe von Funktionen aus der Klasse Flash_cmds an den Funktionszeiger vom Objekt der Klasse Cmd funktioniert nicht:

Fehlermeldung:
Fehler 1 error C3867: "Flash_cmds::setStartaddr": Dem Funktionsaufruf fehlt die Argumentliste. Verwenden Sie "&Flash_cmds::setStartaddr", um einen Zeiger auf den Member zu erstellen. 17

main.cpp
Code:
#define flash_cmds Flash_cmds::getInstance()
void flash_init_52401 (Flash& fl);
void test(const int& ha){std::cout<<"hallo"<<ha;};

int main()
{
	Flash flash;
	
	Cmd* mass_erase= new Cmd("set_startaddr", 1, 1, Flash_cmds::getInstance().setStartaddr);
	mass_erase->Execute();

Cmd.h
Code:
#include <iostream>
#include <string>
#include "string.h"

#pragma once


class Cmd
{
private:

	std::string cmd_name;
	std::string cmd_arg;
	int cmd_id;
	int cmd_argcount;
	void (*cmd_exe)(void);
	void (*cmd_exe_arg)(const int& t );

public:
	Cmd(void);
	~Cmd(void);
	Cmd(std::string name, int id, int argcnt, void (*execute_function)(void));
	Cmd(std::string name, int id, int argcnt, void (*execute_function)(const int&));

	std::string GetName(void)const;
	int GetArgCount(void)const;
	
	void setArg(const std::string& arg);

	void Execute (void) const;

	bool operator==(const std::string& cmd)const
	{
		return(this->GetName()==cmd);
	}
};

Cmd.cpp
Code:
#include "Cmd.h"

Cmd::Cmd(void)
{
}

Cmd::Cmd(const std::string name, const int id, const int argcnt,void (*execute_function)(void) )
: cmd_name(name), cmd_id(id), cmd_argcount(argcnt), cmd_exe(execute_function)
{
	if (argcnt<0)
	{	
		std::cout<<"Ungueltige Anzahl von Argumenten"<<std::endl;
		cmd_argcount=0;
	}

}

Cmd::Cmd(const std::string name, const int id, const int argcnt, void (*execute_function)(const int& t) )
: cmd_name(name), cmd_id(id), cmd_argcount(argcnt),cmd_exe_arg(execute_function)
{
	if (argcnt<0)
	{	
		std::cout<<"Ungueltige Anzahl von Argumenten"<<std::endl;
		cmd_argcount=0;
	}

}




Cmd::~Cmd(void)
{
}

std::string Cmd::GetName (void) const
{
	return Cmd::cmd_name;
}

int Cmd::GetArgCount (void) const
{
	return Cmd::cmd_argcount;
}


void Cmd::Execute (void) const
{
	if(cmd_argcount==1)
		cmd_exe_arg(500);
	else
		cmd_exe();
}

void Cmd::setArg(const std::string& arg)
{
	cmd_arg=arg;
}

Flash_cmds
Code:
//Die Klasse Flash-CMD ist als Singleton-Pattern implementiert. Es kann nur ein Objekt einer 
//Klasse erstellt werden

//#include flash.h
#include <iostream>
#include <fstream> //für ofstream
#include <sstream>
#include <string>
#include "Flash.h"
#include "headertest.h"
//#include "help.h" //für read_file
#pragma once

class Flash_cmds
{

private:
	Flash flash;
	static Flash_cmds* OBJ;
	bool prog_data_content;
	long int *flashbuf;
	long int *filebuf;
	long int * progcontent_arr;
	long int * readcontent_arr;
	char rchar[40];
	int startaddr;
	int endaddr;
	int flashmode;
	bool fdebug;
	std::ofstream prog_file;
	Flash_cmds(void)
	{
		progcontent_arr=0;
		readcontent_arr=0;
		std::cout << "test \n";
	}
	Flash_cmds(const Flash_cmds&);	//nicht kopierbar
	~Flash_cmds(void);
//Konstante für Prog-Content
	 static const int chess=0;
	 static const int invchess=1; 
	 static const int address=2; 
	 static const int array0=3;
	 static const int array1=4; 
	 static const int data_content=5;

//Konstante für Flashmode
	 static const int flash12k=12;
	 static const int flash8k=8; 
	 static const int flash4k=4; 

public:
	
	static Flash_cmds& getInstance();
	static void destroy();
	

	//Get & Set Methoden für Attribute


	int getStartaddr() const;
	int getEndaddr() const;
	int getFlashmode()const;

	void setFlash(const Flash& fl);
	void setStartaddr(const int& saddr);
	void setEndaddr(const int& eaddr);

	void setProgcontent(const int& pgcont);
	void setFlashmode(const int& fmode);

	void start_read(void);
	void start_program(void);
	void start_masserase(void);
	void start_verify(void);
	void start_compare(void);
};

Vielen Dank im Voraus.

Gruß patrick
 
Hallo,

Zeiger auf Membermethoden vertragen sich nicht mit C-Callbacks. Verwende stattdessen z.B. Boost.Function und Boost.Bind. Auf das Wesentliche reduziertes Beispiel (ungetestet! \edit: korrigiert und getestet):

C++:
#include <iostream>

#include <boost/function.hpp>
#include <boost/bind.hpp>

class Flash_cmds
{
private:
    static Flash_cmds* OBJ;

public:
    static Flash_cmds* getInstance() {
        if (!OBJ) OBJ = new Flash_cmds();
        return OBJ;
    }

    void setStartaddr(const int& saddr) {
        std::cerr << saddr << "\n";
    }
};
Flash_cmds* Flash_cmds::OBJ = 0;

class Cmd
{
private:
    boost::function<void()> cmd_exe;
    boost::function<void(const int&)> cmd_exe_arg;

public:
    Cmd(boost::function<void()> execute_function) 
        : cmd_exe(execute_function) {}
    Cmd(boost::function<void(const int&)> execute_function)
        : cmd_exe_arg(execute_function) {}

    void Execute() const {
        if (cmd_exe) {
            cmd_exe();
        } else if (cmd_exe_arg) {
            cmd_exe_arg(500);
        }
    }
};

int main() {
    Cmd cmd(static_cast<boost::function<void(const int&)> >(
        boost::bind(&Flash_cmds::setStartaddr, Flash_cmds::getInstance(), _1)));
    cmd.Execute();
}

Grüße,
Matthias
 
Zuletzt bearbeitet:
Zurück