Forum: PC-Programmierung Parameterliste C++.NET verändern von Variablen ByRef


von Christian (Gast)


Lesenswert?

Hallo Liebe Forenlebewesen,


ich sehe vor lauter Bäume den Wald nicht ...
Ich habe mich eigentlich immer mit native Anwedungen beschäftigt,
muss nun allerding eine .Net Anwedung schreiben ...

In native Code konnte ich folgendes machen:

void func(char *szResult)
{
  strcpy(szResult, "ddd");
};

und die Variable die als szResult übergeben wurde,
wurde auf ddd gesetzt ...

Managed:

void func(String *strResult)
{
  strResult = S"123";
};

Und strResult ist nur solange 123, wie die Funktion nicht
verlassen wird, wird sie verlassen ist die als strResult übergebene
Variable leer ...


Was muss ich hier tun um dennoch den Inhalt der als strResult 
übergebenen
Variable zu ändern ?

Lg und Danke für Antworten


Christian

von Karl H. (kbuchegg)


Lesenswert?

Christian wrote:
>
> In native Code konnte ich folgendes machen:
>
> void func(char *szResult)
> {
>   strcpy(szResult, "ddd");
> };
>
> und die Variable die als szResult übergeben wurde,
> wurde auf ddd gesetzt ...

Das stimmt eigentlich nicht.
Du übergibst hier nicht eine Variable (zumindest keine
Stringvariable), sondern du übergibst die Adresse der
Variablen, also des Arrays in dem du den Text gespeichert
haben möchtest.
Die Adresse die übergeben wird, wird aber nicht geändert.

Dein Aufrufer hat ein Array zur Verfügung:

     +---+---+---+---+---+---+
     |   |   |   |   |   |   |
     +---+---+---+---+---+---+

und beim Aufruf wird die Startadresse des Arrays der Funktion
in einer neuen lokalen Variablen szResult zur Verfügung gestellt:

     +---+---+---+---+---+---+
     |   |   |   |   |   |   |
     +---+---+---+---+---+---+
     ^
     |
     |       szResult
     |       +---------+
     +---------o       |
             +---------+

>
> Managed:
>
> void func(String *strResult)
> {
>   strResult = S"123";
> };
>

Hier passiert aber was ganz anderes:

Der Aufrufer hat ein Stringobjekt und einen Pointer darauf:

   String* pTest = S"abcd";

      pTest
      +-------+      +--------+
      |   o--------->| abcd   |
      +-------+      |        |
                     +--------+

Während des Aufrufes wird beid er Übergabe wieder eine lokale
Variable angelegt, die die Adresse des Stringobjektes enthält
(im Grunde eine Kopie von pTest)

      pTest
      +-------+      +--------+
      |   o--------->| abcd   |
      +-------+   +->|        |
                  |  +--------+
                  |
      strResult   |
      +-------+   |
      |   o-------+
      +-------+

Du erwartest jetzt, dass bei
    strResult = S"123";
der Inhalt des Objektes getauscht wird. Genau das passiert
aber nicht. Es wird ein neues Objekt angelegt und ein
Zeiger darauf in strResult abgelegt

      pTest
      +-------+      +--------+
      |   o--------->| abcd   |
      +-------+      |        |
                     +--------+

      strResult
      +-------+     +-------+
      |   o-------->| 123   |
      +-------+     |       |
                    +-------+

und damit ist auch klar, dass wenn die Funktion beendet wird
und die lokalen Variablen aufgelöst werden, strResult samt
zugehörigem Objekt (hoffentlich) entsorgt werden und dass
pTest immer noch auf das Objekt verweist auf welches er schon
vor dem Aufruf verwiesen hat.

Was du tun musst: Du musst die Adresse von pTest übergeben, nicht
die Adresse die in pTest enthalten ist.

      pTest
      +-------+      +--------+
  +-->|   o--------->| abcd   |
  |   +-------+      |        |
  |                  +--------+
  |
  |   strResult
  |   +-------+
  +------o    |
      +-------+

Jetzt kannst du über strResult direkt den Adresswert in pTest
manipulieren:

Entweder du machst das so:
1
void func(String ** strResult)
2
{
3
   *strResult = S"123";
4
};
5
6
int main()
7
{
8
  String* pTest = S"abcd";
9
  func( &pTest );
10
}

oder aber mehr C++ like
1
void func(String * & strResult)
2
{
3
   strResult = S"123";
4
};
5
6
int main()
7
{
8
  String* pTest = S"abcd";
9
  func( pTest );
10
}


Disclaimer: Alles hier beschriebene ist IMHO, da ich weder
Erfahrung mit managed C++ habe noch einsehe, wozu man das
überhaupt braucht. Entweder ich programmiere C++, dann brauche
ich das Zeugs nicht oder aber ich will managed arbeiten. Dann
nehme ich C#

von Christian (Gast)


Lesenswert?

Hallo Karl Heinz,


danke für Deine Antwort ...
Nun ja, eigentlich ist die Entscheidung für C++ .NET eine reine 
Bauchentscheidung gewesen.

Die Philosophie der verschiedenen Programmiersprachen mal 
vernachlässigt,
ist Deine Erklärung sehr gut, Danke...

Mir ist nur nicht klar, was sich die MS Leute gedacht haben mit dem 
Pointer ...

Du hast aber Recht, das man mit native Code besser arbeiten kann ...


Lg


Christian

von harle (Gast)


Lesenswert?

> Was muss ich hier tun um dennoch den Inhalt der als strResult
> übergebenen
> Variable zu ändern ?

in Visual C++ 2005 einfach so
1
void func(String^ %strResult)
2
{
3
  strResult = "123";
4
};

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.