Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: WinAPI ::  Frage zu Doppelzeiger (IO-Funktion + GetQueuedCompletionStatus)     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Hi
Unregistrierter




Beitrag Hi Unregistrierter 19:31:44 05.09.2010   Titel:   Frage zu Doppelzeiger (IO-Funktion + GetQueuedCompletionStatus)            Zitieren

Hi!

Irgendwie verschiebt sich der Pointer auf overlapped um 4, wenn ich ihn bekomme.

Info:
AcceptEx: http://msdn.microsoft.com/en-us/library/ms737524
GetQueuedCompletionStatus: http://msdn.microsoft.com/en-us/library/aa364986
(Man übergibt AcceptEx eine Adresse, und bekommt sie dann bei GetQueuedCompletionStatus wieder. Bei mir allerdings manchmal 4 Bytes verschoben)


C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
struct Context : public OVERLAPPED
{
// ...
};

// ...

Context* newContext = new Context;

// ...

AcceptEx(..., (OVERLAPPED*)newContext );
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
struct Context : public OVERLAPPED
{
// ...
};

// ...

Context* newContext = new Context;

// ...

AcceptEx(..., (OVERLAPPED*)newContext );
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
struct Context : public OVERLAPPED
{
// ...
};

// ...

Context* newContext = new Context;

// ...

AcceptEx(..., (OVERLAPPED*)newContext );


Ok gut, nun bekomme ich eine completion.

So gehts:

C/C++ Code:
OVERLAPPED* overlapped;

GetQueuedCompletionStatus(..., (OVERLAPPED**)&overlapped);

Context* context = (Context*)overlapped;

// Ok, context == newContext
C/C++ Code:
OVERLAPPED* overlapped;

GetQueuedCompletionStatus(..., (OVERLAPPED**)&overlapped);

Context* context = (Context*)overlapped;

// Ok, context == newContext
C/C++ Code:
OVERLAPPED* overlapped;

GetQueuedCompletionStatus(..., (OVERLAPPED**)&overlapped);

Context* context = (Context*)overlapped;

// Ok, context == newContext


Und so gehts nicht, weil dann context plötzlich 4 Bytes weiter zeigt, als der dem AcceptEx übergebene Context.

C/C++ Code:
Context* context

GetQueuedCompletionStatus(..., (OVERLAPPED**)&context);

// Nicht Ok, context == newContext + 4 (???)
C/C++ Code:
Context* context

GetQueuedCompletionStatus(..., (OVERLAPPED**)&context);

// Nicht Ok, context == newContext + 4 (???)
C/C++ Code:
Context* context

GetQueuedCompletionStatus(..., (OVERLAPPED**)&context);

// Nicht Ok, context == newContext + 4 (???)


Warum ist das so? Zeiger ist doch gleich Zeiger?

THX!
hiii
Unregistrierter




Beitrag hiii Unregistrierter 19:50:42 05.09.2010   Titel:              Zitieren

hast du virtuelle Methoden in deinem Context?
Hi
Unregistrierter




Beitrag Hi Unregistrierter 20:25:46 05.09.2010   Titel:              Zitieren

Danke für den Tip, habs grad mit nem Minimalbeispiel versucht. Liegt tatsächlich am virtuellen Destruktor von Context.

Bin aber viel zu eingerostet in C++, um mir erklären zu können, warum...
Hi
Unregistrierter




Beitrag Hi Unregistrierter 00:21:02 09.09.2010   Titel:              Zitieren

:confused:
Statischer Kasten
Unregistrierter




Beitrag Statischer Kasten Unregistrierter 01:21:20 09.09.2010   Titel:              Zitieren

Nimm static_cast statt C-Casts!
Hi
Unregistrierter




Beitrag Hi Unregistrierter 02:39:14 10.09.2010   Titel:              Zitieren

Bringt nix.
Hi
Unregistrierter




Beitrag Hi Unregistrierter 04:19:29 16.01.2011   Titel:              Zitieren

Need Input
theta
Mitglied

Benutzerprofil
Anmeldungsdatum: 26.09.2008
Beiträge: 3814
Beitrag theta Mitglied 12:02:12 16.01.2011   Titel:              Zitieren

--- hier stand blödsinn ----

Zeiger ist nicht gleich Zeiger - Zeiger auf abgeleitete Klass können anders sein als Zeiger auf Basis Klassen - man denke da nur mal an die Mehrfachvererbung.


Zuletzt bearbeitet von theta am 12:11:17 16.01.2011, insgesamt 3-mal bearbeitet
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13522
Beitrag hustbaer Mitglied 17:05:20 16.01.2011   Titel:              Zitieren

Ich verwende ähnlichen Code öfters, funktioniert wunderbar.
Funktioniert bloss nicht, wenn man nicht korrekt castet.
Wenn du z.B. von "Context" zu "void*" castest, und dann von "void*" zu "OVERLAPPED*", dann wird das nix werden.
Genau so wenn du über void* zurückcastest.
Oder sonst irgendwie Unsinn baust.

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
Hi
Unregistrierter




Beitrag Hi Unregistrierter 17:28:37 16.01.2011   Titel:              Zitieren

hustbaer schrieb:
Wenn du z.B. von "Context" zu "void*" castest, und dann von "void*" zu "OVERLAPPED*", dann wird das nix werden.
Genau so wenn du über void* zurückcastest.

Und wie sonst? Und warum geht das nicht?
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13522
Beitrag hustbaer Mitglied 22:23:58 16.01.2011   Titel:              Zitieren

Du musst direkt von Context* zu OVERLAPPED* casten, damit der Zeiger entsprechend angepasst wird.

Wenn du von Context* zu void* castest, dann darfst du den void* den du bekommst nur wieder zurück zu Context* casten. Den so erhaltenen void* zu einer Basisklasse von Context* zu casten *kann* gehen, ist aber laut Standard undefiniert, und daher einfach falsch.
(Und es geht eben auch oft genug wirklich nicht.)

Alles C++ Grundlagen.

ps.:

BTW: der Fehler ist - wenn dein Beispielcode deinem Programm entspricht - eh ein anderer (sehr ähnlich, aber nix mit void*):
C/C++ Code:
Context* context

GetQueuedCompletionStatus(..., (OVERLAPPED**)&context); // das ist Humbug
C/C++ Code:
Context* context

GetQueuedCompletionStatus(..., (OVERLAPPED**)&context); // das ist Humbug
C/C++ Code:
Context* context

GetQueuedCompletionStatus(..., (OVERLAPPED**)&context); // das ist Humbug

Richtig geht das so:
C/C++ Code:
OVERLAPPED* overlapped;
GetQueuedCompletionStatus(..., &overlapped); // Kein Cast nötig
Context* context = static_cast<Context*>(overlapped); // Jetzt casten wir den Zeiger (was OK ist), und nicht einen Zeiger auf einen Zeiger (was Humbug wäre)
C/C++ Code:
OVERLAPPED* overlapped;
GetQueuedCompletionStatus(..., &overlapped); // Kein Cast nötig
Context* context = static_cast<Context*>(overlapped); // Jetzt casten wir den Zeiger (was OK ist), und nicht einen Zeiger auf einen Zeiger (was Humbug wäre)
C/C++ Code:
OVERLAPPED* overlapped;
GetQueuedCompletionStatus(..., &overlapped); // Kein Cast nötig
Context* context = static_cast<Context*>(overlapped); // Jetzt casten wir den Zeiger (was OK ist), und nicht einen Zeiger auf einen Zeiger (was Humbug wäre)

Der Grund warum es nicht funktioniert, ist dass "Zeiger auf Context" und "Zeiger auf OVERLAPPED" zwei unverwandte Typen sind. Anders gesagt: du kannst nicht T** zu U** casten, egal wie T und U verwandt sind, da T* und U* eben nicht verwandt sind.
Sorry, kann es grad auf die Schnelle nicht besser erklären, bzw. hab keine Zeit es besser/näher zu erklären.

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/


Zuletzt bearbeitet von hustbaer am 22:31:38 16.01.2011, insgesamt 2-mal bearbeitet
zeusosc
Mitglied

Benutzerprofil
Anmeldungsdatum: 01.12.2006
Beiträge: 745
Beitrag zeusosc Mitglied 02:16:31 17.01.2011   Titel:              Zitieren

hustbaer schrieb:
Du musst direkt von Context* zu OVERLAPPED* casten, damit der Zeiger entsprechend angepasst wird.

Wenn du von Context* zu void* castest, dann darfst du den void* den du bekommst nur wieder zurück zu Context* casten. Den so erhaltenen void* zu einer Basisklasse von Context* zu casten *kann* gehen, ist aber laut Standard undefiniert, und daher einfach falsch.
(Und es geht eben auch oft genug wirklich nicht.)

Alles C++ Grundlagen.



Jo,
wenn man eine Inheritclass zu einer baseclass über einen void direkt
konvertiert, muss man darauf achten, dass es die erste Basisklasse ist.
Ansonsten muss der this ptr adjustiert werden,..

Mal grob pseudomäßig:
C/C++ Code:
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
class Inherit:  BaseA, BaseB
{}
//...

LPVOID blub =(LPVOID) new Inerhit;
BaseA* basA = (BaseA) blub; //geht, da nach msdn spec für MSVC BaseA erste addy ist
BaseB* basB = (BaseB) (blub +sizeof(BaseA)); //Adjustiere zeiger
// BaseB liegt hinter BaseA, sizeof(BaseA) sollte auch die die größe der vftbl beinhalten
C/C++ Code:
1
2
3
4
5
6
7
8
class Inherit: BaseA, BaseB
{}
//...

LPVOID blub =(LPVOID) new Inerhit;
BaseA* basA = (BaseA) blub; //geht, da nach msdn spec für MSVC BaseA erste addy ist
BaseB* basB = (BaseB) (blub +sizeof(BaseA)); //Adjustiere zeiger
// BaseB liegt hinter BaseA, sizeof(BaseA) sollte auch die die größe der vftbl beinhalten
C/C++ Code:
1
2
3
4
5
6
7
8
class Inherit:  BaseA, BaseB
{}
//...

LPVOID blub =(LPVOID) new Inerhit;
BaseA* basA = (BaseA) blub; //geht, da nach msdn spec für MSVC BaseA erste addy ist
BaseB* basB = (BaseB) (blub +sizeof(BaseA)); //Adjustiere zeiger
// BaseB liegt hinter BaseA, sizeof(BaseA) sollte auch die die größe der vftbl beinhalten


Die adjustage sollte man aber compiler/architektur-spezifisch explecit nochmal prüfen, bevor man sich darauf verlässt das es "einfach" funktioniert,...

grüßli
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13522
Beitrag hustbaer Mitglied 02:53:28 17.01.2011   Titel:              Zitieren

Zitat:
Jo,
wenn man eine Inheritclass zu einer baseclass über einen void direkt
konvertiert, muss man darauf achten, dass es die erste Basisklasse ist.

Bist du sicher dass das dann definiert ist (laut Standard)?
Ich müsste da erst nachsehen...

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
zeusosc
Mitglied

Benutzerprofil
Anmeldungsdatum: 01.12.2006
Beiträge: 745
Beitrag zeusosc Mitglied 00:58:26 20.01.2011   Titel:              Zitieren

Hi,.

100% sicher bin ich jetzt gerade net,..wo du fragst.
Aber ich schaue mal morgen nach.

gn8

_________________
Der Contrapart in einer Diskussion zu sein, heißt nicht das dieser Standpunkt
der eigene sein muss! ;)
Hi
Unregistrierter




Beitrag Hi Unregistrierter 09:18:40 20.01.2011   Titel:              Zitieren

Ouch, Grundlagenlücke!
Aber: Was, wenn man es statt mit Vererbung so macht:

C/C++ Code:
struct Context
{
    OVERLAPPED overlapped;
    // ...
};
C/C++ Code:
struct Context
{
OVERLAPPED overlapped;
// ...
};
C/C++ Code:
struct Context
{
    OVERLAPPED overlapped;
    // ...
};


Ist "GetQueuedCompletionStatus(..., (OVERLAPPED**)&context);" dann OK? Ich denke schon, denn so, ganz "roh", dürfte ja "Context" und "OVERLAPPED" bis hin zu sizeof(OVERLAPPED) Bytes "speichergleich" sein...
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13519
Beitrag Martin Richter Moderator 11:34:53 20.01.2011   Titel:              Zitieren

Hi schrieb:
Ouch, Grundlagenlücke!
Aber: Was, wenn man es statt mit Vererbung so macht:

C/C++ Code:
struct Context
{
    OVERLAPPED overlapped;
    // ...
};
C/C++ Code:
struct Context
{
OVERLAPPED overlapped;
// ...
};
C/C++ Code:
struct Context
{
    OVERLAPPED overlapped;
    // ...
};


Ist "GetQueuedCompletionStatus(..., (OVERLAPPED**)&context);" dann OK? Ich denke schon, denn so, ganz "roh", dürfte ja "Context" und "OVERLAPPED" bis hin zu sizeof(OVERLAPPED) Bytes "speichergleich" sein...


Nein!
Das hat doch nicht mit Vererbung zu tun.

Außerdem: Versuche casts zu Vermeiden. Gerade wen es hier in keiner Weise nötig ist.

1. Würde ich dennoch den Member in der Context Struktur direkt adressieren.
2. Würde ich nicht darauf bauen, dass overlapped der ertse Parameter der Strutktur bleibt.
3. Wenn überhaupt würde ich von OVERLAPPED ableiten:
Code:
struct Context : public OVERLAPPED
{
    // ...
};
Code:
struct Context : public OVERLAPPED
{
// ...
};
Code:
struct Context : public OVERLAPPED
{
    // ...
};


Aber selbst das ist IMHO mieses Design.
4. Ein Zeiger auf einen Zeiger Overlapped Struktur ist das:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
struct Context
{
    OVERLAPPED overlapped;
    // ...
};

//...
Context myContext;
LPOVERLAPPED p = &myContext.overlapped;
GetQueuedCompletionStatus(..., &p, ...);
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
struct Context
{
OVERLAPPED overlapped;
// ...
};

//...
Context myContext;
LPOVERLAPPED p = &myContext.overlapped;
GetQueuedCompletionStatus(..., &p, ...);
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
struct Context
{
    OVERLAPPED overlapped;
    // ...
};

//...
Context myContext;
LPOVERLAPPED p = &myContext.overlapped;
GetQueuedCompletionStatus(..., &p, ...);

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
Jodocus
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.12.2010
Beiträge: 226
Beitrag Jodocus Mitglied 11:46:04 20.01.2011   Titel:              Zitieren

Geht auch ohne Vererbung mit dem Makro CONTAINING_RECORD() ;)

_________________
Quak
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13519
Beitrag Martin Richter Moderator 13:05:29 20.01.2011   Titel:              Zitieren

Jodocus schrieb:
Geht auch ohne Vererbung mit dem Makro CONTAINING_RECORD() ;)


Ich habe doch geschrieben, dass es ohne Vererbung geht und auch besser wäre...
Ich verstehe Deinen Einwurf nicht.
Zudem löst es nicht das Grundproblem, dass der OP nämlich einen Zeiger auf einen Zeiger benötigt!

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
Jodocus
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.12.2010
Beiträge: 226
Beitrag Jodocus Mitglied 13:22:35 20.01.2011   Titel:              Zitieren

>> dass der OP nämlich einen Zeiger auf einen Zeiger benötigt!

Hä? Den braucht er doch überhaupt nicht.
Mein Post war kein Einwand, sondern eine gängige Möglichkeit, aus einem Member das Container-Objekt zu ermitteln (was auch funktioniert, wenn OVERLAPPED nicht der erste Member der Struktur ist). :confused:

_________________
Quak
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13519
Beitrag Martin Richter Moderator 15:09:56 20.01.2011   Titel:              Zitieren

Jodocus schrieb:
Hä? Den braucht er doch überhaupt nicht.


Nicht?

Dann schau Dir mal die Definition von GetQueuedCompletionStatus an.
http://msdn.microsoft.com/en-us/library/aa364986(VS.85).aspx

Nach meinem Dafürhalten ist "LPOVERLAPPED *lpOverlapped" ein Zeiger auf einen Zeiger, und damit hat der OP anscheinend Probleme...
Just my 2 cents!

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
Hi
Unregistrierter




Beitrag Hi Unregistrierter 17:12:09 20.01.2011   Titel:              Zitieren

Ich glaube, ich verwende lieber den completion key (unsigned int*) :D
Sollte eigentlich genau so klappen. Man hat dann halt keine verschiedenen Kontexte für zB. AcceptEx und WSARecv, aber dann packt man halt alles nötige in eine einzige ClientContext-Struktur.
Oder warum sollte man das nicht machen?
Jodocus
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.12.2010
Beiträge: 226
Beitrag Jodocus Mitglied 17:30:54 20.01.2011   Titel:              Zitieren

Huch, da hab ich das LP überlesen, sorry Martin. :D
Anyway, das Problem ist ja nicht der Doppelzeiger, mit dem hat er ja eigentlich fast nichts zu tun, bisauf das Übergeben der Adresse.

@ TS: Das ist doch ganz einfach:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
enum operation_type {
  accept, send, recv, ...
};

// POD
struct container {
   operation_type type;
   WSAOVERLAPPED overlapped;
};

container c = new container;
std::memset(c, sizeof *c, 0);
c->type = accept;
AcceptEx(..., c, ...);

...

WSAOVERLAPPED* ol_ptr = 0;
GetQueuedCompletionStatus(..., &ol_ptr, ...);
container* con_ptr = CONTAINING_RECORD(ol_ptr, container, overlapped);
event_workers[con_ptr->type](..., con_ptr, ...);
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
enum operation_type {
accept, send, recv, ...
};

// POD
struct container {
operation_type type;
WSAOVERLAPPED overlapped;
};

container c = new container;
std::memset(c, sizeof *c, 0);
c->type = accept;
AcceptEx(..., c, ...);

...

WSAOVERLAPPED* ol_ptr = 0;
GetQueuedCompletionStatus(..., &ol_ptr, ...);
container* con_ptr = CONTAINING_RECORD(ol_ptr, container, overlapped);
event_workers[con_ptr->type](..., con_ptr, ...);
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
enum operation_type {
  accept, send, recv, ...
};

// POD
struct container {
   operation_type type;
   WSAOVERLAPPED overlapped;
};

container c = new container;
std::memset(c, sizeof *c, 0);
c->type = accept;
AcceptEx(..., c, ...);

...

WSAOVERLAPPED* ol_ptr = 0;
GetQueuedCompletionStatus(..., &ol_ptr, ...);
container* con_ptr = CONTAINING_RECORD(ol_ptr, container, overlapped);
event_workers[con_ptr->type](..., con_ptr, ...);

Mit dem CONTAINING_RECORD-Makro erhälst du den Container, der das OVERLAPPED-Objekt enthält (intern natürlich per Casts). In einem Array von Funktoren kannst du dann entsprechende Funktionen sammeln, die über eine Operation-ID dispatcht werden.

>> Ich glaube, ich verwende lieber den completion key (unsigned int*) :D

Den solltest du benutzen, aber nicht für Per-I/O-Daten. Der Completion-Key ist für gewöhnlich der Socket-Deskriptor, auf dem die Operation stattgefunden hat. ;)

Edit: Hoffentlich bist du auch über den korrekten Umgang mit AcceptEx() aufgeklärt.

_________________
Quak


Zuletzt bearbeitet von Jodocus am 17:35:11 20.01.2011, insgesamt 2-mal bearbeitet
........
Unregistrierter




Beitrag ........ Unregistrierter 18:12:03 20.01.2011   Titel:              Zitieren

WSAOVERLAPPED overlapped; <- müsste dann aber die erste Membervariable sein, damit es funktioniert
Jodocus
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.12.2010
Beiträge: 226
Beitrag Jodocus Mitglied 18:18:53 20.01.2011   Titel:              Zitieren

Nö, der Offset wird intern abgezogen. ;)
Wird bei mir jedenfalls so definiert:
C/C++ Code:
#define CONTAINING_RECORD(address,type,field) ((type* )( (PCHAR)(address) - (ULONG_PTR)(&((type )0)->field)))
C/C++ Code:
#define CONTAINING_RECORD(address,type,field) ((type* )( (PCHAR)(address) - (ULONG_PTR)(&((type )0)->field)))
C/C++ Code:
#define CONTAINING_RECORD(address,type,field) ((type* )( (PCHAR)(address) - (ULONG_PTR)(&((type )0)->field)))

_________________
Quak
........
Unregistrierter




Beitrag ........ Unregistrierter 18:21:39 20.01.2011   Titel:              Zitieren

Dann darfst du aber bei AcceptEx nicht direkt c übergeben sondern &c.overlapped
Hi
Unregistrierter




Beitrag Hi Unregistrierter 18:27:50 20.01.2011   Titel:              Zitieren

Hmm, guck ich mir mal an.

Jodocus schrieb:
Den solltest du benutzen, aber nicht für Per-I/O-Daten.

Warum nicht? Kann auch gleich eine ganze Struktur übergeben.
Und ich brauche ja pro Client nicht mehr als einen Kontext und einen WSARecv-Aufruf.
Dann bei GetQueuedCompletionStatus() habe ich den Clientkontext verfügbar. Ist doch genau so wie mit dem OVERLAPPED *.

Jodocus schrieb:
Edit: Hoffentlich bist du auch über den korrekten Umgang mit AcceptEx() aufgeklärt.

Vielleicht kannst du dazu noch kurz was erwähnen? :) (Außer natürlich, dass man sich unbedingt den Funktionszeiger holen sollte. Und vllt. noch setsockopt mit SO_UPDATE_ACCEPT_CONTEXT. Und natürlich immer schön null-initialisierte OVERLAPPED-Strukturen zu verwenden :rolleyes: :) ).
Jodocus
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.12.2010
Beiträge: 226
Beitrag Jodocus Mitglied 18:43:01 20.01.2011   Titel:              Zitieren

>> Dann darfst du aber bei AcceptEx nicht direkt c übergeben sondern &c.overlapped

Logo. ;)

>> Warum nicht? Kann auch gleich eine ganze Struktur übergeben.

Weil eine Verbindung nicht viel mit einer Operation zu tun hat. Per-Handle-Data und Per-I/O-Data sind doch in diesem Kontext verschieden.
Für Per-Handle-Data speichert man so Sachen wie Socket-Deskriptor, gesendete/empfangene Bytes, Adresse etc., hingegen benutzt die Per-I/O-Data für Sachen wie Fehlercode, Puffer, Operationstyp etc. Wenn du das alles in eine einzige monolithische Struktur presst, hast du oft Informationen an manchen Stellen, die du gar nicht brauchst.
Du kannst es natürlich machen, technisch spricht auch nichts dagegen. Es ist eben üblich, I/O-Completionports auf diese Weise zu handhaben. (jaja, ich weiß, Dogmatismus :D)

>> Vielleicht kannst du dazu noch kurz was erwähnen?

Benutzt du den übergebenen Puffer, um gleich auch Daten vom Client zu empfangen?

_________________
Quak


Zuletzt bearbeitet von Jodocus am 18:44:24 20.01.2011, insgesamt 3-mal bearbeitet
Hi
Unregistrierter




Beitrag Hi Unregistrierter 19:32:11 20.01.2011   Titel:              Zitieren

Alles klar, werd ich bedenken. Danke!

Jodocus schrieb:
Benutzt du den übergebenen Puffer, um gleich auch Daten vom Client zu empfangen?

Nope. Hab ich lieber gelassen, wegen stale clients.
Macht für mich auch irgendwie überhaupt keinen Sinn, bei AcceptEx schon was zu empfangen. Wobei... soll das etwa für "Autorisierungen" sein?
Jodocus
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.12.2010
Beiträge: 226
Beitrag Jodocus Mitglied 20:29:19 20.01.2011   Titel:              Zitieren

>> Wobei... soll das etwa für "Autorisierungen" sein?

Nö, für Performance. Du kannst im Kernelmode gleich 2 Operationen ausführen, anstatt explicit WSARecv() zu benutzten (du sparst dir einen switch in den Usermode). Aber schon AcceptEx() brauchst du nur bei äußerster Performance. Was programmierst du überhaupt?

>> Nope. Hab ich lieber gelassen, wegen stale clients.

Dafür gibt es ja Lösungsmöglichkeiten. ;)

_________________
Quak
Hi
Unregistrierter




Beitrag Hi Unregistrierter 21:22:10 20.01.2011   Titel:              Zitieren

Jo, aber wenn's nicht sein muss...

Eigentlich nur nen kleinen Server/Client Core für ein, zwei kleinere zukünftige Projekte.
Aber das Prinzip completion ports gefällt mir am besten. Deshalb möchte ich es verwenden und mich nicht mit select-Gefrickel o.Ä. herumschlagen und auch gleich was lernen.
Jodocus
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.12.2010
Beiträge: 226
Beitrag Jodocus Mitglied 21:51:04 20.01.2011   Titel:              Zitieren

Naja, nachdem du dir das angeguckt hast, kannst du auch gleich zu boost::asio greifen. :)

_________________
Quak
C/C++ Forum :: WinAPI ::  Frage zu Doppelzeiger (IO-Funktion + GetQueuedCompletionStatus)   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.