Dauerhaftes Abspeichern von Adressen



  • Aufgrund des etwas nichtssagenden Titels einfach mal nen Code-Beispiel:

    typedef VOID (WINAPI* tExitProcess) (UINT uExitCode);
    static  VOID (WINAPI* pExitProcess) (UINT uExitCode);
    
    VOID FillPtr( VOID ) {
    	HINSTANCE hK32 = LoadLibraryA( "Kernel32.dll" );
    
    	pExitProcess = (tExitProcess)GetProcAddress( hK32, "ExitProcess" );
    }
    
    UINT AnotherOne( VOID ) {
    	pExitProcess( 0x00 );	// pExitProcess = 0x00000000
    }
    

    Irgendwie steh ich auf dem Schlauch! Hoffe jemand kann mir helfen 😉
    MfG, 0x2A



  • Nochmal kurz als Ergänzung:
    Ich möchte die Variable pExitProcess in einer Prozedur einmalig initialisieren und diese soll dann auch für alle weiteren Prozeduren verwendbar sein.

    MfG



  • Machst du doch schon.
    Wäre natürlich zweckmäßig, FillPtr bei Programmstart auch einmal aufzurufen.



  • Ja.
    Wo soll das Problem sein?

    Bis auf dass pExitProcess static ist, was natürlich zu einem Problem führt, wenn du FillPtr und AnotherOne in unterschiedlichen Übersetzungseinheiten definierst.

    Davon abgesehen müsste das funktionieren.

    Und davon abgesehen dass du, wenn du LoadLibrary aufrufst, auch FreeLibrary aufrufen solltest. (Was natürlich bei der KERNEL32 eine Fleissaufgabe ist - geht einfach um's Prinzip, bzw. darum dass man sich solche Unarten gleich garnicht angewöhnt.)
    Man könnte ja schliesslich bei KERNEL32 auch GetModuleHandle statt LoadLibrary verwenden...



  • Hihi.
    0x2A
    Auch nicht schlecht 🙂



  • (answer to life, the universe and everything) in binary

    answer to life, the universe and everything = 0b101010



  • Hier noch einmal (die etwas komplexere) Sachlage:

    Ich verwende in einem Projekt eine von mir geschriebene Library. Die Library setzt sich aus verschiedenen Übersetzungseinheiten und aus einer Header-Datei. In der Header-Datei sind die verschiedenen Funktionen definiert ( pExitProcess usw.). #pragma once ist gesetzt. Eine Übersetzungseinheit dient zum Befüllen der Pointer aus der Header-Datei. Diese Initialisierungs-Funktion wird in der Main-Prozedur als erstes aufgerufen und daraufhin werden die Pointer verwendet. Leider sind diese nicht initialisiert.

    Kurze Übersicht:

    EinHeader.h

    #pragma once
    #include <windows.h>
    
    UINT FillPointer();
    
    . . .
    
    typedef INT			(WINAPI* tCompareStringA)		(LCID Locale, DWORD dwCmpFlags, LPCSTR lpString1, INT cchCount1, LPCSTR lpString2, INT cchCount2);
    static  INT			(WINAPI* pCompareStringA)		(LCID Locale, DWORD dwCmpFlags, LPCSTR lpString1, INT cchCount1, LPCSTR lpString2, INT cchCount2);
    
    typedef INT			(WINAPI* tCompareStringW)		(LCID Locale, DWORD dwCmpFlags, LPCWSTR lpString1, INT cchCount1, LPCWSTR lpString2, INT cchCount2);
    static  INT			(WINAPI* pCompareStringW)		(LCID Locale, DWORD dwCmpFlags, LPCWSTR lpString1, INT cchCount1, LPCWSTR lpString2, INT cchCount2);
    
    typedef LPSTR		(WINAPI* tlstrcatA)				(LPSTR lpString1, LPCSTR lpString2);
    static  LPSTR		(WINAPI* plstrcatA)				(LPSTR lpString1, LPCSTR lpString2);
    
    typedef LPWSTR		(WINAPI* tlstrcatW)				(LPWSTR lpString1, LPCWSTR lpString2);
    static  LPWSTR		(WINAPI* plstrcatW)				(LPWSTR lpString1, LPCWSTR lpString2);
    
    . . .
    

    Initialisierungs-Übersetzungseinheit.cpp

    #include "EinHeader.h"
    
    UINT FillPointer2() {
    	HINSTANCE hKernel32 		= (HINSTANCE)					/* . . . */;
    
    	pGetProcAddress 			= (tGetProcAddress) 			/* . . . */;
    	pLoadLibraryA   			= (tLoadLibraryA)				/* . . . */;
    
    	. . .
    
    	pGetCommandLineA			= (tGetCommandLineA)			pGetProcAddress( hKernel32, "GetCommandLineA" );
    
    	pExitProcess		= (tExitProcess)pGetProcAddress( hKernel32, "ExitProcess" );
    
    	. . .
    
    	return 0;
    }
    

    Main.cpp

    #include "EinHeader.h"
    
    int WINAPI WinMain( /* . . . */ ) {
    	FillPointer();
    	pExitProcess( 0 );		/* Unhandled exception at 0x00000000 in ........exe: 0xC0000005: Access violation reading location 0x00000000. */
    							/* Beim hovern über den Pointer: 0x00000000 */
    	return 0;
    }
    

    Das ist nun natürlich eine stark vereinfachte Darstellung. Sie soll nur als Schema dienen und kann Tipp-Fehler/Code-Fehler enthalten.

    Wenn ich für die Pointer in der Header-Datei anstatt " static " " extern " o.ä. verwende kommt es zu einem Linker-Error, da die Pointer mehrfach definiert wurden... ist ja logisch 😉

    Ich hoffe, dass ich nichts vergessen habe.
    MfG, 0x2A



  • Inzwischen bin ich dann auch darauf gekommen, dass es unklug war die Pointer als static zu definieren.

    Meine Frage nun: Wie sollte ich sie definieren, damit sie in allen Übersetzungsheiten bekannt sind und nicht zu Linker-Fehlern wegen Mehrfach-Definition führen?

    MfG



  • In Header:
    extern int Foo;

    In Source:
    int Foo;

    Ist allerdings sehr schlechter Stil.



  • Gibt einen Linkerfehler bei dem Projekt, welches die Library verwendet:

    error LNK2001: unresolved external symbol "void (__stdcall* pExitProcess)(unsigned int)" (?pExitProcess@@3P6GXI@ZA)

    Habe die Methode schon getestet. Müssen noch Änderungen an dem Projekt vorgenommen werden, welches die .lib verwendet?

    MfG, 0x2A



  • Habe es nun lösen können. Mein Fehler lag darin, dass ich in den Header zwar

    extern int foo;

    geschrieben hatte doch in der Quelldatei nur

    `#include "foo.h"

    void bar( void ) {

    int foo;
    
    . . .
    

    }`

    anstatt

    `#include "foo.h"

    int foo;

    void bar( void ) {

    . . .
    

    }`

    Hoffe jemand kann die Info noch brauchen 🙂
    MfG


Anmelden zum Antworten