Code einer Templatefunktion klassenextern definieren



  • Hallo

    wie müsste der Syntax bzw. Code aussehen wenn ich den Code der Funktion Read() klassenextern schreiben möchte. Also über "Cmemory::Read"

    #ifndef __CMEMORY_H_
    #define __CMEMORY_H_
    
    class Cmemory
    {
    	char *pProcexename;
    	char *pProcwinname;
    	bool SetDebugPrivileges();
    public:
    	HANDLE	hproc;			// processhandle
    	LPDWORD	PID;			// processID
    	Cmemory::Cmemory();
    	// todo Destructor
    	bool	Init(char szProcexename[]=0, char szProcwinname[]=0);
    	bool    OpenProc();
    	bool	GetStatus();
    	bool	ReadMem(DWORD& address, char* recvBuf, int& size);
    	template <typename datatype> datatype Read(DWORD& address) // <- Read() klassenintern
    	{
    		datatype recvData = 0;
    		ReadMem(address, (char*)&recvData, sizeof(datatype));
    		return recvData;
    	}
    };
    
    /*
    template <typename datatype> datatype Cmemory::Read(DWORD& address) // Fehler, wie wäre der Syntax um das klassenextern zu lösen
    {
        datatype recvData = 0;
        ReadMem(address, (char*)&recvData, sizeof(datatype));
        return recvData;
    }
    */
    
    #endif // __CMEMORY_H_
    

    Ich versuche das erste mal mit einem Template zu arbeiten. Die Funktion Read() in meiner Cmemory-Klasse soll in der lage sein folgende Datentypen auszulesen:
    unsigned char
    signed char
    unsigned __int16
    signed __int16
    unsigned long
    signed long
    unsigend __int64
    signed __int64
    double
    float

    ...hoffe das funktionert auf diesem Weg.



  • Mach mal aus den DWORD-Referenzen (DWORD&) DWORD-Pointer (DWORD*). Dann sollte das passen.

    /e: und warum nicht memcpy() statt ReadMem()?



  • memcpy() funktioniert meines wissens nur solange man im Adressraum des eigenen Prozess kopiert. Bei mir handelt es sich um einen fremden Prozess. Ausnahme: DLL-Injection, das möchte ich aber nicht und wäre auch zu umständlich.

    Die Parameter für Read() sollten möglichst 'by reference' übergeben werden, das sollte schneller sein als 'by value' (denke ich zumindest). Allerdings musste ich in diesem Fall für die Adresse noch ein "const" hinzufügen, sonnst kommt es zu Fehlern beim Compilieren.

    aber mein eigentliches Problem:
    Ich will nur den Funktionsprototyp direkt in der Klasse definieren und den eigentlichen Code für Read außerhalt. Nur ich weiß nicht wie man das in Verbindung mit einem Template macht.

    irgnedwie so:

    // Cmemory.h
    class Cmemory
    {   
        // other stuff
        template <typename datatype> bool Read(const unsigned long& address, datatype& recvBuf);
    }
    
    // Cmemory.cpp
    template <typename datatype> bool Cmemory::Read(const unsigned long& address, datatype& recvBuf)
    {
        if (ReadProcessMemory(hproc, (LPVOID)address, &recvBuf, sizeof(datatype), 0)==0)
            return false;    // something went wrong
        return true;    // memory read ok
    }
    

    ... generiert Linkerfehler:

    1>main.obj : error LNK2019: unresolved external symbol "public: bool __thiscall Cmemory::Read<float>(unsigned long const &,float &)" (??Read@M@Cmemory@@QAE\_NABKAAM@Z) referenced in function _main 1>main.obj : error LNK2019: unresolved external symbol "public: bool \_\_thiscall Cmemory::Read(unsigned long const &,char &)" (??Read@D@Cmemory@@QAE_NABKAAD@Z) referenced in function _main

    Der Compiler versuch die Funktion einmal für char und für float zu generieren - damit teste ich atm die Funktion.

    So funktioniert es wunderbar:

    #ifndef __CMEMORY_H_
    #define __CMEMORY_H_
    
    class Cmemory
    {
    	char *pProcexename;
    	char *pProcwinname;
    	bool SetDebugPrivileges();
    public:
    	HANDLE	hproc;			// processhandle
    	LPDWORD	PID;			// processID
    	Cmemory::Cmemory();
    	// todo Destructor
    	bool	Init(char szProcexename[]=0, char szProcwinname[]=0);
    	bool    OpenProc();
    	bool	GetStatus();
    	template <typename datatype> bool Read(const unsigned long& address, datatype& recvBuf)
    	{
    		if (ReadProcessMemory(hproc, (LPVOID)address, &recvBuf, sizeof(datatype), 0)==0)
    			return false;	// something went wrong
    		return true;	// memory read ok
    	}
    };
    
    #endif // __CMEMORY_H_
    


  • Kann es sein, dass Du noch VC6 benutzt???



  • Ich verwende MS Visual Studio 2008.



  • Ich habe mal aus den DWORD Referenzen DWORD Pointer gemacht, das compiliert bei mir einwandfrei. Den Tipp hatte ich Dir aber schon gegeben....


Anmelden zum Antworten