www.mikrocontroller.net

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


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
void func(String ** strResult)
{
   *strResult = S"123";
};

int main()
{
  String* pTest = S"abcd";
  func( &pTest );
}

oder aber mehr C++ like
void func(String * & strResult)
{
   strResult = S"123";
};

int main()
{
  String* pTest = S"abcd";
  func( pTest );
}


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#

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: harle (Gast)
Datum:

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

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.