[C++/CLI] Object naar variabele kopiëren.

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • DoubleJOnline
  • Registratie: Juni 2007
  • Laatst online: 27-05 07:07
Hallo,

Ik zit nu enkele dagen met C++/CLI te programeren en stuit nu op een probleem dat ik niet heb kunnen oplossen.

Ik heb de volgende test class:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
namespace TestClasses {

    using namespace System::Net::Sockets;

    public ref class ClientThread {
    private:
        TcpClient^ client;
    public:
        ClientThread(TcpClient^ newClient);
        static void ConnectionHandler();
    };

}

In deze class heb ik de volgende Constructor functie:
code:
1
2
3
4
TestClasses::ClientThread::ClientThread(TcpClient^ newClient)
{
    client = newClient;
}

Bedoeling is, dat wanneer ik een instance van deze class aanmaak, een TcpClient mee geef aan de private: client variable.

In de functie ConnectionHandler staat bijvoorbeeld het volgende:
code:
1
2
3
4
5
void TestClasses::ClientThread::ConnectionHandler()
{
    NetworkStream^ stream = client->GetStream();
    // Doe iets met stream.....
}


Hoe krijg ik het nu in mijn constructor voor elkaar dat hij, ofwel een kopie, ofwel naar newClient verwijst, zodat ik deze in de rest van mijn object kan gebruiken.

Dus een beetje dit idee (c voorbeeldje):
code:
1
2
3
4
5
6
void printIets(int i) {
int *j;
j = &i;
(*j)++;
printf("%d", i);
}

Acties:
  • 0 Henk 'm!

  • Nick The Heazk
  • Registratie: Maart 2004
  • Laatst online: 07-09-2024

Nick The Heazk

Zie jij er wat in?

Je probeert vanuit de statische methode ConnectionHandler een instance variable (client) te gebruiken. Dat gaat natuurlijk niet werken, per definitie van een statische methode.

Als je problemen ondervindt is het voor ons ook veel gemakkelijker indien je de foutmelding van je compiler ook vermeld. De MS compilers geven normaliter zeer duidelijke foutenboodschappen :).

[ Voor 52% gewijzigd door Nick The Heazk op 01-10-2009 12:42 ]

Performance is a residue of good design.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

DoubleJOnline schreef op donderdag 01 oktober 2009 @ 12:22:
In de functie ConnectionHandler staat bijvoorbeeld het volgende:
code:
1
2
3
4
5
void TestClasses::ClientThread::ConnectionHandler()
{
    NetworkStream^ stream = client->GetStream();
    // Doe iets met stream.....
}
Dat kan niet, want ConnectionHandler is static, en voor 'client' heb je een instance nodig.
Hoe krijg ik het nu in mijn constructor voor elkaar dat hij, ofwel een kopie, ofwel naar newClient verwijst, zodat ik deze in de rest van mijn object kan gebruiken.
Ik snap niet wat je hier nou mee bedoelt eigenlijk? Wie is "hij"? Geef eens een voorbeeld met pseudocode.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • DoubleJOnline
  • Registratie: Juni 2007
  • Laatst online: 27-05 07:07
Doel is het volgende.
Ik probeer een simpele client/server applicatie te maken waarin de server tekst messages ontvangt van de client en deze uitprint.

code die de server uitvoert is:

-> Start TcpListener
-> in While lus, accepteer een TcpClient.
-> Start een apart Thread waarin de Client wordt "afgehandeld".

Ik probeer dit te bereiken door een object te maken, die ik dan als aparte thread uitvoer.

Waar het fout gaat, is het volgende. Na de constructor, start ik de functie die de client moet afhandelen.
Wanneer ik de code:
code:
1
NetworkStream^ stream = client->GetStream();
heb geeft hij de volgende fout:
.\ClientThread.cpp(22) : error C2227: left of '->GetStream' must point to class/struct/union/generic type

Acties:
  • 0 Henk 'm!

  • JaWSnl
  • Registratie: Maart 2007
  • Laatst online: 13-06 15:18
DoubleJOnline schreef op donderdag 01 oktober 2009 @ 13:10:
code:
1
NetworkStream^ stream = client->GetStream();
heb geeft hij de volgende fout:
.\ClientThread.cpp(22) : error C2227: left of '->GetStream' must point to class/struct/union/generic type
Het lijkt alsof hij niet weet wat een TcpClient is. Heb je wel de juiste include gedaan?

There are only 10 types of people in the world: those who understand binary and those who don't.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nogmaals, je ConnectionHandler is static. Er is dus geen 'this' pointer in die methode, en dus kun je 'client' ook niet accessen omdat er geen object is om 'm vanaf te halen.

.edit: overigens is dit typisch een geval waarin de foutmelding dus niet duidelijk is ;)

[ Voor 21% gewijzigd door .oisyn op 01-10-2009 13:42 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Nick The Heazk
  • Registratie: Maart 2004
  • Laatst online: 07-09-2024

Nick The Heazk

Zie jij er wat in?

Op de volgende code

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>

class Test {
    public:
    Test() : client(0) {};
    
    std::vector<int> client;

    static void bla() {
        std::cout << client.size();
    }
};

int main() {
    Test a;
    Test::bla();
}


is GCC zelfs nog onduidelijker:
code:
1
2
3
4
heazk@laptopnick:/tmp$ g++ test.cpp
test.cpp: In static member function "static void Test::bla()":
test.cpp:8: error: invalid use of member "Test::client" in static member function
test.cpp:11: error: from this location


De Intel compiler doet het wat beter:
code:
1
2
3
4
5
6
heazk@laptopnick:/tmp$ LC_ALL=C icc test.cpp
test.cpp(11): error: a nonstatic member reference must be relative to a specific object
        std::cout << client.size();
                     ^

compilation aborted for test.cpp (code 2)

Performance is a residue of good design.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik vind anders dat die de lading 100% dekt hoor :). Hij zegt dat je member "client" niet mag gebruiken in een static member function.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
testapp.cpp(16) : error C2597: illegal reference to non-static member 'Test::m_member'

Combineer die met de GCC versie, dat dekt alles.

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

  • Laurens-R
  • Registratie: December 2002
  • Laatst online: 29-12-2024
Mijn advies: verdiep je eerst in de basisconcepten achter OOP. Je loopt hier namelijk tegen fundamentele fouten op, die gemakkelijk kan vermijden door je te verdiepen in de eerdergenoemde basisconcepten.

Je kan normale members alleen maar benaderen vanuit de context van een object instance. Bijvoorbeeld

code:
1
this->ObjectMember


of


code:
1
SomeObjectInstance->ObjectMember


(even er van uitgaande dat je members benaderd via een pointer naar het object).

[ Voor 41% gewijzigd door Laurens-R op 01-10-2009 15:08 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

NC83 schreef op donderdag 01 oktober 2009 @ 14:57:
testapp.cpp(16) : error C2597: illegal reference to non-static member 'Test::m_member'
Het punt is, zodra je een member access operator (. of ->) gebruikt op zo'n member komt ie ineens met C2227 of C2228 8)7

[ Voor 5% gewijzigd door .oisyn op 01-10-2009 15:20 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Laurens-R
  • Registratie: December 2002
  • Laatst online: 29-12-2024
Dat klopt omdat hij dingen probeert die hij niet hoort te doen. Als je een beetje kennis hebt van hoe classes etc werken, zou je helemaal niet tegen dit probleem aanlopen.

In de code hierboven is de method bla static. Dan moet je niet met dingen gaan klooien die op basis van een instance werken.

[ Voor 27% gewijzigd door Laurens-R op 01-10-2009 16:25 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sorry, maar lees je überhaupt de topic of roep je gewoon maar wat nav de startpost?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Laurens-R
  • Registratie: December 2002
  • Laatst online: 29-12-2024
Als jij iets anders in deze logmeldingen leest hoor ik het graag:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
 heazk@laptopnick:/tmp$ g++ test.cpp
test.cpp: In static member function "static void Test::bla()":
test.cpp:8: error: invalid use of member "Test::client" in static member function
test.cpp:11: error: from this location 

De Intel compiler doet het wat beter:
code:
 heazk@laptopnick:/tmp$ LC_ALL=C icc test.cpp
test.cpp(11): error: a nonstatic member reference must be relative to a specific object
          std::cout << client.size();
                       ^

compilation aborted for test.cpp (code 2)


Bijbehorende code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream> 
#include <vector> 

class Test { 
    public: 
    Test() : client(0) {}; 
     
    std::vector<int> client; 

    static void bla() { 
        std::cout << client.size(); 
    } 
}; 

int main() { 
    Test a; 
    Test::bla(); 
}


Tuurlijk gaat dat niet werken

bla is een static method... deze roept een normale member aan die niet static is...

Mis ik nu iets... en ik weet dat jij dit antwoordt ook heb gegeven... het enige wat ik daarna opmerkte is dat als de TS dit niet snapt dat je je wellicht even moet verdiepen in hoe OOP/classes in elkaar zit.

[ Voor 35% gewijzigd door Laurens-R op 01-10-2009 16:51 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ah ok, duidelijk, je leest dus niet.

Het ging erom wát de errormelding precies zei, niet waaróm er een error was. En als je mijn eerste reactie in deze draad had gelezen dan had je ook door dat ik snapte waarom die error er was, maar daar gaat het sinds de 4e reactie in de topic al niet meer om.
EvilB2k schreef op donderdag 01 oktober 2009 @ 16:46:
Mis ik nu iets... en ik weet dat jij dit antwoordt ook heb gegeven... het enige wat ik daarna opmerkte is dat als de TS dit niet snapt dat je je wellicht even moet verdiepen in hoe OOP/classes in elkaar zit.
Ja dat snap ik ook wel, maar ik reageerde toch ook niet op jouw post, of wel? :)

[ Voor 48% gewijzigd door .oisyn op 01-10-2009 16:53 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Laurens-R
  • Registratie: December 2002
  • Laatst online: 29-12-2024
spuit 11: excuses volgens mij volg ik het niet meer helemaal... ik ga snel in een hoekje mezelf zitten schamen |:(

* zucht ik ga wat eerder naar huis van m'n werk *

[ Voor 22% gewijzigd door Laurens-R op 01-10-2009 16:54 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nou, even voor de duidelijkheid dan ;). Het gaat om de errormelding die VC++ geeft. Bij deze code:
C++:
1
2
3
4
5
6
struct Foo { int i; };
struct Bar
{
    Foo * foo;
    static void baz() { foo; }
};

Geeft hij:
error C2597: illegal reference to non-static member 'Bar::foo'

Mooie error imho, zegt precies wat er aan de hand is.
Verander je je code naar dit:
C++:
1
2
3
4
5
6
struct Foo { int i; };
struct Bar
{
    Foo * foo;
    static void baz() { foo->i; }
};

Dan zegt ie ineens
error C2227: left of '->i' must point to class/struct/union/generic type

Wat onzin is, want foo *is* een pointer naar struct type. Imho moet hij hier ook gewoon C2597 geven. Dit lijkt me overigens een bug, en geen bewuste keuze.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • user109731
  • Registratie: Maart 2004
  • Niet online
Eén van de doelstellingen van LLVM Clang is duidelijke foutmeldingen.

Dan krijg je dus zulke dingen (inclusief kleurtjes):
[b]test.cpp:8:25: [red]error:[/] invalid use of member 'foo' in static member function[/b]
    static void baz() { foo->i; } 
                        [b][green]^[/][/]
1 diagnostic generated.

[ Voor 3% gewijzigd door user109731 op 01-10-2009 20:14 ]


Acties:
  • 0 Henk 'm!

  • DoubleJOnline
  • Registratie: Juni 2007
  • Laatst online: 27-05 07:07
Ik geloof inderdaad dat mijn vraag niet helemaal duidelijk is geweest.

Wat ik probeer te bereiken in C++ is ongeveer het volgende, dit is even een illustratie van een eventuele JAVA implementatie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class ClientTest {
    
    private Socket client;
    
    ClientText(Socket newClient)
    {
        this.client = newClient;
    }
    
    handleConnection {
        try {
            InputStream is = this.client.getInputStream();
            OutputStream os = this.client.getOutputStream();
            // overige code om data te ontvangen en te verzenden.
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class mainProgram {
    public static int main(String[] args)
    {
        try {
            int port = 7777;
            server = new ServerSocket(port);
            Socket socket = server.accept();
            ClientTest client = new ClientTest(socket);
            client.handleConnection();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}


Ik probeer dus een class ClientTest aan te maken, waarbij ik in de constructor de Socket aan een interne private variabele probeer te koppelen. De manier waarop ik dit dus nu probeer is uiteraard dus niet de juiste, aangezien ik hier met static en nonstatic functies/variabelen zit te werken. Dit wist ik niet.

Vraag is dus nu, hoe ik een dergelijke JAVA constructie dus voor elkaar zou kunnen krijgen in C++/CLI.

Hoop dat hiermee duidelijk is geworden, wat ik probeer te bereiken in C++.

Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Waarom is de de methode ConnectionHandlerstatic in het eerste geval. Moet je die functie ergens zo gebruiken TestClasses::ConnectionHandler.
Zo ja dan kan deze functie eigenlijk alleen maar met globals of static data werken.

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

  • DoubleJOnline
  • Registratie: Juni 2007
  • Laatst online: 27-05 07:07
NC83 schreef op vrijdag 02 oktober 2009 @ 10:24:
Waarom is de de methode ConnectionHandlerstatic in het eerste geval. Moet je die functie ergens zo gebruiken TestClasses::ConnectionHandler.
Zo ja dan kan deze functie eigenlijk alleen maar met globals of static data werken.
Ah, nu zie ik het.

Die is daar gekomen door dat ik een heb geprobeerd om de ConnectionHandler functie uit te laten voeren als een aparte Thread en deze dus in het voorbeeld 'static' was.

In ieder geval iedereen bedankt voor de antwoorden, zie nu waar dingen fout zijn gegaan. Nu weer verder met mijn testprojectje.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sjongejonge, dat stond dus al in de eerste reply 8)7

[ Voor 11% gewijzigd door .oisyn op 02-10-2009 11:16 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 18-08 21:31
JanDM schreef op donderdag 01 oktober 2009 @ 20:11:
Eén van de doelstellingen van LLVM Clang is duidelijke foutmeldingen.

Dan krijg je dus zulke dingen (inclusief kleurtjes):
[b]test.cpp:8:25: [red]error:[/] invalid use of member 'foo' in static member function[/b]
    static void baz() { foo->i; } 
                        [b][green]^[/][/]
1 diagnostic generated.
Dan hebben ze nog wel wat werk te doen, want deze foutmelding is niet echt duidelijk. Dat het "invalid use" is is allang duidelijk, anders had je geen foutmelding gekregen. Het zou juist ook moeten zeggen waarom het gebruik ongeldig is.
Pagina: 1