Parameterübergabe: Übersetzung von "REF" aus C# nach C++
-
Hallo,
wie ich schon in meinem vorherigen Beitrag schrieb, versuche ich den C#-Quelltext von http://www.codeproject.com/cs/miscctrl/loadandsave.asp in C++ zu übersetzen.
Das wesentliche habe ich bereits fertig, aber ein weiteres Problem (bei der Parameterübergabe), bekomme ich selbst einfach nicht gelößt:public static int loadTree(TreeView tree, string filename) { if (File.Exists(filename)) { // Datei öffnen Stream file = File.Open(filename, FileMode.Open); // Binär-Formatierer init. BinaryFormatter bf = new BinaryFormatter(); // Object var. init. object obj = null; try { // Daten aus der Datei deserialisieren obj = bf.Deserialize(file); } catch (System.Runtime.Serialization.SerializationException e) { MessageBox.Show("De-Serialization failed : {0}", e.Message); return -1; } // Datei schliessen file.Close(); // Neues Array erstellen ArrayList alist = obj as ArrayList; // Für jedes Objekt in der ArrayList foreach (object item in alist) { // Objekt in Hashtable konvertieren Hashtable ht = item as Hashtable; // Neue TreeNode erstellen TreeNode tn = new TreeNode(ht["Text"].ToString()); // Daten aus dem Hash laden tn.Tag = ht["Tag"]; tn.ImageIndex = Convert.ToInt32(ht["SelectedImageIndex"].ToString()); tn.SelectedImageIndex = Convert.ToInt32(ht["SelectedImageIndex"].ToString()); // die Parent-Child-Zuordnung string fPath = ht["FullPath"].ToString(); // FullPath teile in ein string-Array string[] parts = fPath.Split(tree.PathSeparator.ToCharArray()); // Wenn das Array mind. 2 Teile hat if (parts.Length > 1) { // ParentNode variable init. TreeNode parentNode = null; TreeNodeCollection nodes = tree.Nodes; // rekursives durchsuchen der Nodes searchNode(parts, ref parentNode, nodes); if (parentNode != null) { // Eine ParentNode wurde gefunden, also aktuelle Node unter dieser hinzuf. parentNode.Nodes.Add(tn); } } // Ansonsten Node nur zum Tree hinzuf. else tree.Nodes.Add(tn); } return 0; } else return -2; // File existiert nicht } private static void searchNode(string[] parts, ref TreeNode parentNode, TreeNodeCollection nodes) { foreach (TreeNode n in nodes) { // Wenn der Text der TreeNode (n) dem der ParentNode (laut FullPath) entspricht if (n.Text.Equals(parts[parts.Length - 2].ToString())) { // ParentNode setzen parentNode = n; // ende return; } // ansonsten -> rekursiver Aufruf dieser Funktion else searchNode(parts, ref parentNode, n.Nodes); } } #endregion }
Meine Übersetzung:
static int loadTree(TreeView * tree, String * filename) { if (System::IO::File::Exists(filename)) { // Datei öffnen System::IO::Stream * file = System::IO::File::Open(filename, System::IO::FileMode::Open); // Binär-Formatierer init. System::Runtime::Serialization::Formatters::Binary::BinaryFormatter * bf = new System::Runtime::Serialization::Formatters::Binary::BinaryFormatter(); // Object var. init. Object * obj = 0; try { // Daten aus der Datei deserialisieren obj = bf->Deserialize(file); } catch (System::Runtime::Serialization::SerializationException * e) { MessageBox::Show("Ent-Serialisation gescheitert : {0}", e->Message); } file->Close(); tree->Nodes->Clear(); // Neues Array erstellen ArrayList * alist = new ArrayList(); alist = static_cast<ArrayList *>(obj); for (int i = 0; i < alist->get_Count(); i++) { Object * item = alist->Item[i]; // Objekt in Hashtabelle konvertieren Hashtable * ht = new Hashtable(); ht = static_cast<Hashtable *>(item); TreeNode * tn = new TreeNode(ht->get_Item(S"Text")->ToString()); // Daten aus dem Hash laden tn->Tag = ht->get_Item(S"Tag"); // die Parent-Child-Zuordnung String * fPath = ht->get_Item(S"FullPath")->ToString(); //MessageBox::Show(fPath); // FullPaht-Teile in ein string-Array String * parts[] = fPath->Split(tree->PathSeparator->ToCharArray()); // MessageBox::Show(parts->Item->); // Wenn das Array mind. 2 Teile hat if (parts->Length > 1) { // ParentNode variable init. TreeNode * parentNode = new TreeNode(); parentNode = 0; TreeNodeCollection * nodes = tree->Nodes; searchNode(parts, *parentNode, nodes); if (parentNode != 0) { // Eine ParentNode wurde gefunden, also akutelle Node unter dieser hinzuf. parentNode->Nodes->Add(tn); } } else tree->Nodes->Add(tn); } return 0; } else return -2; }
Das Problem liegt, glaube ich zumindest, bei der Übergabe des Parameters parentNode an die Funktion searchNode.
static void searchNode(String * parts[], TreeNode &parentNode /* !!!! DIESER PARAMETER !!!! */, TreeNodeCollection * nodes) { //MessageBox::Show("searchNode"); for (int i = 0; i < nodes->get_Count(); i++) { MessageBox::Show("Schleife"); TreeNode * n = new TreeNode; n = nodes->Item[i]; // Wenn der Text der TreeNode (n) dem der ParentNode (laut FullPath) entspricht if (n->Text->Equals(parts[parts->Length - 2]->ToString())) { // ParentNode setzen parentNode.Nodes->Clear(); parentNode->Nodes.Add(nodes->Item[i]); //ende return; } else { searchNode(parts, parentNode, n->Nodes); } } }
-
Ich habe das jetzt nicht alles durchgelesen, aber so sollte es gehen
void searchNode(String * parts[], TreeNode ** parentNode /* !!!! DIESER PARAMETER !!!! */, TreeNodeCollection * nodes)
-
Alzo das ist schon ein heikles Thema. Ausserdem solltest du diese Techniken nicht zu häufig verwenden, da sonst dein Quelltext unlesbar wird.
#pragma managed System::Void refptr(System::String __gc *__gc *Ref) { (*Ref) = S"Hallo Welt\n"; } System::Int32 main() { System::String __gc *Str; refptr(&Str); System::Console::Out->Write(Str); return 0; }
Das ist vielleicht nicht ganz das gleiche, aber es könnte dir helfen. Du musst nur darauf achten, das du niemals die Adresse eines lokalen Objekts mit return übergibst, denn das gibt Probleme
.
-
Danke für die Antworten!
Das Problem scheint nun gelößt zu sein.
@Scania: Deinen Vorschlag habe ich sofort ausprobiert, aber der Compiler war mit dieser Lösung nicht so recht zufrieden.
-
???
Bei mir funktioniert dies Einwandfrei, genauso wie der Compiler automatisch "" in __gc umwandelt, wandelt er auch "**" in __gc* __gc* um.