[Dev-C++] Fremde DLL statisch linken

Fummel nix im Treiber direkt rum. Die erkennung des OS ist wichtig, da der Teil den du als default gemacht hast, bei NT-OS benötigt wird.
 
@shade37337
Ok. Ich lade mir das mal runter. Auch wenn es mir wahrscheinlich nix bringt. Damit könnte ich dann höchstens nachvollziehen können, wie man auf den negativen Wert bei dieser DeviceIoControl() Fkr kommt.

@MagicAndre1981
Ja, ich habe das wieder in "case 2" geändert. Der Fehler war ganz einfach, dass ich vergesen hatte sysver zu initialisieren.
Bzw. die Variable sollte eigentlich in der DLLMAIN initialisiert werden, aber das scheint wohl nicht zu funktionieren.
PHP:
BOOL APIENTRY DllMain( HINSTANCE  hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 ) {

	hmodule = hModule;
	switch(ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
		                          sysver = SystemVersion();
		                          if(sysver==2)
			                            Opendriver();
	    break;
	    case DLL_PROCESS_DETACH:
                                  if(sysver==2)
			                            CloseHandle(hdriver);
        break;
	}
    return TRUE;
}
Ich hab die Initialisierung jetzt einfach in den case 2 Block geschrieben. Das hat aber bestimmt Performanceverluste zur Folge, weil jetzt bei jedem Aufruf der Fkt. erst der Treiber geladen muss.

Naja, erstmal testen ob es überhaupt funtioniert.
 
Beim statischen linken könnte ich mir vorstellen, das DllMain nicht gerufen wird. Ansonsten funktioniert das sehr wohl.

Ausserdem wenn das Programm jetzt in beiden Fällen korrekt durchläuft, was hast Du denn geändert? Das & vor dem buffer halte ich für einen guten Grund, das es jetzt geht.

MfG

Arnd
 
Also ich habe das Programm gerade einem Kumpel geschickt, der sich ein Gerät zum testen des Parallel Ports gebaut hat. Der hat gesagt, dass es geht. Also am Gerät sind 8 Lampen und die kann man ein und ausschalten, indem man das entsprechende Bitmuster nach Port 0x378 sendet. Ich hab in ner Schleife schnell ein Lauflicht geschrieben.
00000001
00000010
00000100
00001000
00010000
00100000
01000000
10000000

Diese Werte werden übergeben.
Die Schleife sieht so aus:
PHP:
void delay(DWORD time) {
     DWORD end = time + GetTickCount();
     while(end > GetTickCount()) { }
}

    const short base = 0x378;
    short bits = 1;
    for(int i=0;i<8;i++) {       
            Out32(base, bits);
            bits = bits << 1;
            delay(1000);
    }

Und nun ein Changelog:
  • Ich habe das & an der Stelle bei buffer in der Fkt DeviceIoControl() entfernt.
  • Die Funktionen, die exportiert werden, waren vorher so deklariert.
    PHP:
    void _stdcall Out32(short PortAddress, short data);
    short  _stdcall Inp32(short PortAddress);
    Das hab ich geändert in:
    PHP:
    extern "C" _stdcall __declspec (dllexport) void Out32(short portAdr, short data);
    extern "C" _stdcall __declspec (dllexport) short Inp32(short portAdr);
    Beim Importieren halt entsprechend: __declspec (dllimport)
  • Wie schon richtig bemerkt wird die dllmain beim statischen einbinden nicht aufgerufen. Dadurch hatte ich das Problem, dass hModule nicht gesetzt wurde, was ich für die Funktionen FindResource() und LoadResource() brauche. Ich musste hModule also vor dem Aufruf der Funktionen initialisieren. Und zwar mit: hmodule = LoadLibrary("myPort.dll");
    Das hat natürlich den Nachteil, dass man die dll nicht umbenennen kann. Aber ich hab mir gedacht: Wenn man die dll eh schon statisch linkt (bei dynamisch ist es eigentlich auch so), dann darf man die dll eh nicht umbenennen.
  • Wenn dieser Treiber (hwinterface.sys) nicht gefunden wurde, dann muss er erst in das Verzeichnis System32\Drivers kopiert und aktiviert werden. Hierzu musste ich den Treiber als Resource in die Dll einbinden. Das musste ich eigentlich nur verändern, weil ich nen anderen Compiler habe und hat wahrscheinlich nichts mit dem eigentlichen Fehler zu tun.
  • In der Testphase habe ich mir an wichtige cout's gesetzt, damit ich sehen konnte, was das Programm macht. Ich habe so gesehen, dass der Treiber erst nicht gefunden wurde. Dann wurde die hwinterface.sys in den System32\Drivers kopiert und installiert. Danach konnte er bei jedem Aufruf von Out32() und Inp32() gleich geladen werden.
  • Bei der Fallunterscheidung zwischen WinNT und Win9x musste ich den Befehl _inp() bzw. _outp() auskommentieren, weil mein Compiler den nicht kennt. D.h. auf einem Win9x System würde gar nichts passieren. Den Fehler kann ich leicht beheben, indem ich nen Compiler nehme, der den Befehl kennt. Borland oder so.
So. Und schließlich funktioniert alles. Ich bekomme nur noch die Compiler-Warnung wegen der negativen Zahl im Parameter. Die würde ich aber ganz leicht mit (DWORD) wegbekommen.

Also. Vielen, vielen Danke für die Hilfe. Ich werde das Programm nochmal selbst in der Schule testen, erwarte aber keine Schwierigkeiten.
 
Zuletzt bearbeitet:
Prima das es geht, aber das extern "C" ist doch eigentlich in Deinem CPP Programm nötig und nicht in der DLL?

Damit bindet man externe C Funktionen in ein C++ Programm ein.

MfG

Arnd
 
Hast recht. Ohne geht es auch. Aber dann sehen die Funktionsnamen in der Definitionsdatei komisch aus.
Code:
EXPORTS
	_Z5Inp32s@4 @ 1
	_Z5Out32ss = _Z5Out32ss@8 @ 2
	_Z5Out32ss@8 @ 3
	_Z5Inp32s = _Z5Inp32s@4 @ 4
Das extern "C" stand außerdem so in der Beispieldatei von Dev-C++. Deshalb hab ichs einfach mal übernommen.
 
Zurück
Oben