Autor Beitrag
Borsty
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Sa 06.09.08 16:38 
Moinsen, ich hätte da ma 'n Problem ^^

Ich schreib zZ an einem Progrämmchen zum überwachen und steuern von Gameservern auf Source-Engine Basis (HL2,CSS,etc)
(Durch Zufall) bin ich dann vor kurzem auf eine Bibliothek direkt von Valve (von denen ist HL2 usw ^^) gestoßen um die dedizierten Server direkt anzusprechen. Geliefert wird eine .dll inkl. Hifle und Header datei für C/C++. (Link)

Eigentlich sollte es ja kein Problem sein das ganze für Delphi verwendbar zu machen, allerdings bin ich da auf was gestoßen womit ich (noch) nichts anfangen kann :(

Folgendes:
ausblenden Quelltext
1:
typedef(WINAPI* SSQ_CALLBACK)(DWORD type,PSSQ_REPLY_UNION reply);					


"SSQ_CALLBACK" ist ein "typedef union":
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
typedef union
{
  PSSQ_BATCH_REPLY batch_reply;
  char* log_reply;
  PSSQ_RULES_REPLY rules_reply;
  char* rcon_reply;
  BOOL log_notify;
} SSQ_REPLY_UNION, *PSSQ_REPLY_UNION;


"SSQ_CALLBACK" wird auch später in einer Funktion als Parameter erwartet.

Im Anhang mal der gesamte header und mein bisheriger Versuch für Delphi (Der soweit auch funktioniert, nur halt alles was im zusammenhang mit diesem SSQ_CALLBACK ist funktioniert nicht :/).
Einloggen, um Attachments anzusehen!
Borsty Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mo 08.09.08 14:23 
Keiner ne Idee? :/
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 08.09.08 19:04 
Kannst Du bitte mal schauen, ob Du die Offsets der einzelnen Felder in C (und das Sizeof des Datentyps) rausbekommst? Daraus sollte sich das ganze Rekonstruieren lassen ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Di 09.09.08 12:04 
Hm, sehe ich den Wald aufgrund von Übermüdung vor lauter Bäumen nicht, oder ist
ausblenden Quelltext
1:
typedef(WINAPI* SSQ_CALLBACK)(DWORD type,PSSQ_REPLY_UNION reply);					
nicht vielmehr eine (Art) Deklaration eines Funktionszeigertyps als eines unions? Dann wäre die Pascal-Version davon mit meinen eingerosteten Delphi-Kenntnissen vermutlich sowas wie
ausblenden Delphi-Quelltext
1:
type SSQ_CALLBACK: function(DWORD type; PSSQ_REPLY_UNION reply): ???					
Den Rückgabetyp der Funktion kann ich gerade nicht bestimmen, normalerweise kenne ich WINAPI als __stdcall, hier scheint da entweder noch ein Typ mit reindefiniert worden zu sein, oder das ist kein valides C++. Je nach Belegung von WINAPI und Standardkonformität des ursprünglichen Compilers tut's dann auch ein procedure.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 09.09.08 12:39 
user profile icontommie-lie hat folgendes geschrieben:
Hm, sehe ich den Wald aufgrund von Übermüdung vor lauter Bäumen nicht, oder ist
ausblenden Quelltext
1:
typedef(WINAPI* SSQ_CALLBACK)(DWORD type,PSSQ_REPLY_UNION reply);					
nicht vielmehr eine (Art) Deklaration eines Funktionszeigertyps als eines unions? Dann wäre die Pascal-Version davon mit meinen eingerosteten Delphi-Kenntnissen vermutlich sowas wie
ausblenden Delphi-Quelltext
1:
type SSQ_CALLBACK: function(DWORD type; PSSQ_REPLY_UNION reply): ???					
Den Rückgabetyp der Funktion kann ich gerade nicht bestimmen, normalerweise kenne ich WINAPI als __stdcall, hier scheint da entweder noch ein Typ mit reindefiniert worden zu sein, oder das ist kein valides C++.

Ich kann dich schon mal beruhigen ... das ist valides C++ :P

user profile icontommie-lie hat folgendes geschrieben:
Je nach Belegung von WINAPI und Standardkonformität des ursprünglichen Compilers tut's dann auch ein procedure.

Jain ... Wenn dich der Rückgabewert nicht interessiert schon, sobald da aber was anderes als void für den Typ steht, IST es bei korrekter Übersetzung eine Function.

Übersetzen wir mal per Hand:
ausblenden C#-Quelltext
1:
typedef(WINAPI* SSQ_CALLBACK)(DWORD type,PSSQ_REPLY_UNION reply);					

typedef --> type

Erste Klammer:
WINAPI --> stdcall
* SSQ_CALLBACK --> Funktionszeiger, Typname SSQ_CALLBACK

Parameter:
DWORD type --> _type: DWORD;
PSSQ_REPLY_UNION reply --> reply: PSSQ_REPLY_UNION;

Setzt man das also zusammen:
ausblenden Delphi-Quelltext
1:
type SSQ_CALLBACK: procedure(_type: DWORD; reply: PSSQ_REPLY_UNION); stdcall;					


Bzgl. der Union mal die genannten Werte ermittelt?

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Di 09.09.08 13:12 
user profile iconBenBE hat folgendes geschrieben:
Ich kann dich schon mal beruhigen ... das ist valides C++ :P
Hrmpf *patsch*
Nein, isses nicht, aber es ist valides ISO-C99. In C++ kannst du keine Funktionen ohne Rückgabetyp deklarieren (Ausnahmen siehe unten). In C ist es implizit int. War mir auch neu, aber ich habe nie viel mit ISO/ANSI-C gemacht, daß ich da so fit für solche Feinheiten bin. Das erklärt allerdings, warum einige Hempels in C++ main(void)(sic!) schreiben...
Aber C++ isses trotzdem nich ;-)

BenBE hat folgendes geschrieben:
user profile icontommie-lie hat folgendes geschrieben:
Je nach Belegung von WINAPI und Standardkonformität des ursprünglichen Compilers tut's dann auch ein procedure.

Jain ... Wenn dich der Rückgabewert nicht interessiert schon, sobald da aber was anderes als void für den Typ steht, IST es bei korrekter Übersetzung eine Function.
Ja, das weiß ich. Deswegen schrob ich "je nach Belegung von WINAPI". Enthält WINAPI keinen Typ, so ist es invalides C++ (oder aber valides C, siehe oben), steht da void, ist es eine procedure, steht da int oder sonstwas, ist es eine function.
Bei gängigen Belegungen von WINAPI ist der Code nur valid, wenn es C-Code sein soll, also ist es automatisch int, also ist es eine function SSQ_CALLBACK(...): Integer; (mit Vorsicht zu genießen, int ist garantiert mindestens 16 bit groß, normalerweise 32, auf IA64 64bit (auf x86-64 lustigerweise nicht/nicht immer), das mit den Delphi-Typen, die feste Größen vorschreiben, zu übersetzen, kann nach Hinten losgehen.)


<advocacy>
ISO-C++ Standard, 7.0.1 hat folgendes geschrieben:
Only in function declarations for constructors, destructors, and type conversions can the decl-specifier-seq be omitted.78)

Die Fußnote auf selbiger Seite hat folgendes geschrieben:
The “implicit int” rule of C is no longer supported.

</advocacy>

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 09.09.08 13:31 
Man brauch (wenn man den Rückgabewert nicht benötigt) in seiner Delphi-Übersetzung diesen nicht beachten. Das Ergebnis wird bei stdcall nämlich in EAX zurückgegeben, wo Delphi von Haus aus davon ausgeht, dass das nach einem Prozeduraufruf undefiniert ist...

Ansonsten geb ich tommie-lie Recht. (Wobei die ISOs hab ich auch nicht immer im Kopf).

@tommie-lie: Ansonsten die Übersetzung aber soweit korrekt?

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Di 09.09.08 14:23 
user profile iconBenBE hat folgendes geschrieben:
Ansonsten geb ich tommie-lie Recht. (Wobei die ISOs hab ich auch nicht immer im Kopf).
Göttin bewahre, im Kopf habe ich die Zitate auch nicht, du hast mich verunsichert, deshalb habe ich nachgeschlagen ;-)

BenBE hat folgendes geschrieben:
@tommie-lie: Ansonsten die Übersetzung aber soweit korrekt?
Ich hatte mir nur das aus der Frage angeschaut, aber beim Drüberschauen fällt folgendes auf:
ausblenden Quelltext
1:
2:
3:
4:
#define SSQ_GS_TIMEOUT 1<<0
#define SSQ_LOG_TIMEOUT 1<<1
#define SSQ_MS_TIMEOUT 1<<2
#define SSQ_RCON_TIMEOUT 1<<3

wird zu
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
const
  SSQ_GS_TIMEOUT = 1;
  SSQ_LOG_TIMEOUT = 2;
  SSQ_MS_TIMEOUT = 4;
  SSQ_RCON_TIMEOUT = 8;
und nicht zu 0, 1, 2 und 3.

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
enum
{
  SSQ_USA_EAST = 0,
  SSQ_USA_WEST,
  SSQ_SOUTH_AMERICA,
  SSQ_EUROPE,
  SSQ_ASIA,
  SSQ_AUSTRALIA,
  SSQ_MIDDLE_EAST,
  SSQ_AFRICA,
  SSQ_WORLD = 255
};
Werte in enums, die nicht explizit festgelegt werden, haben immer einen um 1 erhöhten Wert als der vorher in der Liste stehende, also ist
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
    SSQ_USA_EAST = 0;
    SSQ_USA_WEST = 1;
    SSQ_SOUTH_AMERICA = 3;
    SSQ_EUROPE = 7;
    SSQ_ASIA = 15;
    SSQ_AUSTRALIA = 31;
    SSQ_MIDDLE_EAST = 63;
    SSQ_AFRICA = 127;
    SSQ_WORLD = 255;
falsch, richtig wäre 0, 1, 2, 3, ..., 7, 255 hat. Das gleiche gilt für die anderen enums, die als Konstanten übersetzt wurden (warum eigentlich nicht als Delphi-enum übersetzen?).

Bei
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  SSQ_INFO_REPLY = record
    version: Char;
    hostname: Array[0..255of Char;
    map: Array[0..31of Char;
    game_directory: Array[0..31of Char;
    game_description: Array[0..255of Char;
    app_id: SmallInt;
    num_players: Char;
    max_players: Char;
    num_of_bots: Char;
    dedicated: Char;
    os: Char;
    password: Char;
    secure: Char;
    game_version: Array[0..31of Char;
  end;
lassen sich die Typen für version, app_id, num_players, max_players und num_of_bots wohl besser durch einen ShortInt übersetzen. Anstatt arrays of Char sind ShortStrings (hostname: String[256];) wahrscheinlich handlicher. Und für die restlichen Chars dürfte ein Byte oder ShortInt auch besser passen (eigentlich ByteBool, aber ich kenne die genaue Semantik dieses Typs in Delphi nicht mehr, möglicherweise entstehen unliebsame "-1 == True != True == 1"-Probleme).
Ähnliches gilt für die Records SSQ_PLAYER_ITEM und SSQ_PLAYER_REPLY. Weiterhin an allen Records das Schlüsselwort packed nicht vergessen. Die ganzen vars in den Funktionsdeklarationen haben da nichts zu suchen, im C-Header stehen da weder Pointer, noch nur in C++ existierende Referenzen, also nix var, sondern by-value!

Mehr fällt mir erstmal nicht auf.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 09.09.08 14:54 
user profile icontommie-lie hat folgendes geschrieben:
Bei
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  SSQ_INFO_REPLY = record
    version: Char;
    hostname: Array[0..255of Char;
    map: Array[0..31of Char;
    game_directory: Array[0..31of Char;
    game_description: Array[0..255of Char;
    app_id: SmallInt;
    num_players: Char;
    max_players: Char;
    num_of_bots: Char;
    dedicated: Char;
    os: Char;
    password: Char;
    secure: Char;
    game_version: Array[0..31of Char;
  end;
lassen sich die Typen für version, app_id, num_players, max_players und num_of_bots wohl besser durch einen ShortInt übersetzen. Anstatt arrays of Char sind ShortStrings (hostname: String[256];) wahrscheinlich handlicher.

Aber falsch ;-) Bei Shortstrings in Delphi ist das erste Byte die Längenangabe, diese ist in char-Arrays bei C nicht vorhanden. Daher ist die Übersetzung mit Array of char schon korrekt. Kann in Delphi genauso wie ein normaler String behandelt werden (bis auf einige kleine Ausnahmen).

user profile icontommie-lie hat folgendes geschrieben:
Und für die restlichen Chars dürfte ein Byte oder ShortInt auch besser passen (eigentlich ByteBool, aber ich kenne die genaue Semantik dieses Typs in Delphi nicht mehr, möglicherweise entstehen unliebsame "-1 == True != True == 1"-Probleme).

Nur wenn man True = 1 ausgeht. Die Semantik in Delphi für ByteBool ist wie bei C: =0 --> false, !=0 --> True.

user profile icontommie-lie hat folgendes geschrieben:
Ähnliches gilt für die Records SSQ_PLAYER_ITEM und SSQ_PLAYER_REPLY. Weiterhin an allen Records das Schlüsselwort packed nicht vergessen. Die ganzen vars in den Funktionsdeklarationen haben da nichts zu suchen, im C-Header stehen da weder Pointer, noch nur in C++ existierende Referenzen, also nix var, sondern by-value!

Maximal const darf ergänzt werden ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Borsty Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mi 10.09.08 11:06 
Hmm

ausblenden Quelltext
1:
typedef(WINAPI* SSQ_CALLBACK)(DWORD type,PSSQ_REPLY_UNION reply);					

Hab mir die Doku mal angeguckt und da gibts als Rückgabewert einen BOOL also von daher denk ich mal:
ausblenden Delphi-Quelltext
1:
SSQ_CALLBACK = function( typ: DWORD; reply: PSSQ_REPLY_UNION ):BOOL; StdCall;					


Bzgl. der union hatte ich noch kein Glück.
Das mit den enums ist mir im nachhinein auch aufgefallen, trotzdem danke ^^
'var' in den Funktionsdefinitionen wurden durch 'const' ersetzt.