Zeiger auf Referenz als Funktionsparameter
-
Hallo zusammen,
Ich habe folgendes Problem:
Ich nutze die Programmierschnittstelle eines CAD-Systems (Visual Basic 6) und bin nun auf DLLs einer externen Firma angewiesen. Diese DLLs sind in C++ programmiert.//#######Definition der Funktion in der DLL######## #define dll_intern extern "C" __declspec(dllimport) //################################################## dll_intern bool _cdecl LoadSTL (const char* fnm, T3DVECF *& P, int32 & n, TRIANGLE *& T, int32 & m); //################################################## typedef signed long int32; // 32 Bit mit Vorzeichen struct T3DVECF { public: float x; float y; float z; };Betrachtet man z.B. die oben dargestellte Funktion, so erkennt man, dass der Funktion ein String und des Weiteren ein Zeiger auf eine Referenz auf T3DVECF übergeben wird. T3DVECF ist dabei eine Struktur, bestehend aus drei float.
Im Programm wird anschließend mittels
P = new T3DVECF [n];Speicher für P allokiert. P ist also vielmehr ein Array aus Strukturen, welche wiederum aus drei float bestehen. Die Elementanzahl des Array steht erst zur Laufzeit des Programms fest. Da Visual Basic keine Pointer kennt, möchte ich den Umweg über eine eigene C++-DLL gehen. Diese C++-DLL soll dann die VB-gerechte Datenaufbereitung übernehmen. Aber wie kann ich nun von meinem C++-Programm auf dieses Array zugreifen? Die oben definierte Funktion ist vorgegeben, d.h. ich muss einen Doppelzeiger (oder ist es etwa keiner?) nutzen. Wie müsste der Funktionsaufruf in meiner Applikation aussehen? Wie müssen die Daten an dieser Stelle definiert werden?
Gibt es hierzu elegantere Alternativen? Intensive Internet-Recherche brachte hierzu keine Lösung.Für ein ganz simples Beispiel zur Veranschaulichung wäre ich wirklich sehr dankbar (z.B. hochzählen eines Werts, also P[1].x += 1;).
Ich bin absoluter C++-Anfänger und bitte um Entschuldigung für etwaigen Missbrauch von C++-Begriffen. Ich bin wirklich für jede Form der Anregung dankbar und hoffe, dass mir jemand bei diesem für mich sehr wichtigen Problem helfen kann. Vielen Dank!
-
P ist ein Array von T3DVECF. Und der Zugriff funktioniert genau so, wie du ihn als Beispiel hingeschrieben hast.. Wo ist das Problem?!
-
Ich weiß einfach nicht wie ich in meiner Applikation das Array definiere und anschließend als Übergabeparameter an meine Funktion LoadSTL weiterreiche. Es ist wahrscheinlich ganz simpel, aber ich weiß es einfach nicht.
Mein Vorschlag für den Funktionsaufruf:
bool retval; const char* path; T3DVECF* punkteliste; T3DVECF* dreiecksliste; int32 a; int32 b; retval = LoadSTL(path, punkteliste, a, dreiecksliste, b);Aber das stimmt doch sicherlich hinten und vorne nicht. Tut mir leid, aber ich habe da momentan echte Schwierigkeiten mit. Vielen Dank für evtl. Hilfe.
-
Mal abgesehen davon, dass es nicht viel Sinn macht einen Zeiger per Referenz zu übergeben stimmt das so.
int foo ( int* list , int count) { ... } int main () { int l[500]; foo (l , 500); }Wichtig ist nur, dass du, wenn du ein Array übergibst auch noch die Anzahl der Objekte mitübergibst, da das alleine durch den Zeiger nicht (immer) absehbar ist.
btw:
Warum probierst du so Zeugs nicht einfach mal an einem kleinem Beispiel aus? - Und wenn es das macht, was du erwartest, (respektive überhaupt kompilieren lässt), dann ist gut, ansonsten kannst du hier nachfragen, warum etwas wie funktioniert, oder wie nicht..
-
Okay, Du hast natürlich Recht mit dem Testen. Aber das habe ich auch schon zig mal probiert. Bin wie gesagt absolut unbedarft in Sachen C++. Ich muss es aber lösen. Ich habe nun mal ein kleines Beispiel versucht:
#include "stdafx.h" #include "stdio.h" #include <iostream> using namespace std; typedef signed long int32; // 32 Bit mit Vorzeichen struct T3DVECF { public: float x; float y; float z; }; struct TRIANGLE { public: int32 i; int32 j; int32 k; }; bool LoadSTL (const char* fnm, T3DVECF *& P, int32 &n, TRIANGLE *& T, int32 &m) { P = new T3DVECF[10]; P[1].x = 1; return true; } int _tmain() { const char* fnm; T3DVECF* P = new T3DVECF[4]; TRIANGLE* T = new TRIANGLE[2]; int n; int m; LoadSTL(fnm, &P[4], n, &T[2], m); std::cout << P[1].x << "\n\n"; delete[] P; delete[] T; std::cin.get(); return 0; }Wenn ich das kompiliere, erhalte ich folgende Fehlermeldung:
"error C2664: 'LoadSTL': Konvertierung des Parameters 2 von 'T3DVECF *__w64 ' in 'T3DVECF *&' nicht möglich"Muss ich bei der Übergabe der Arrays bereits die Größe mit übergeben? Denn in der Funktion (später wird es eine DLL. Hab es jetzt nur mal versucht einfach zu halten.) wird später noch der Speicherbereich erweitert.
Vielen Dank schon einmal für die bisherige Hilfe!
-
LoadSTL(fnm, &P[4], n, &T[2], m);Das hier ist schon mal ziemlicher Käse.

mal schauen, was du da machst.
&P[4]Ergibt dir die Adresse des 5ten Elementes aus dem Array. Selbst wenn sich das kompilieren lassen lässe, würdest du einen ziemlich heftigen Laufzeit Fehler an den Kopf geschmissen bekommen.
- Schau dir nochmal mein Beispiel an.
-
drakon schrieb:
&P[4]Ergibt dir die Adresse des 4ten Elementes aus dem Array.
Du meinst wohl des 5ten Elementes
(nanana drakon, setzt die Verkalkung ein *duck*)
-
asc schrieb:
drakon schrieb:
&P[4]Ergibt dir die Adresse des 4ten Elementes aus dem Array.
Du meinst wohl des 5ten Elementes
(nanana drakon, setzt die Verkalkung ein *duck*)Was den? - Habe ich ja geschrieben.. :p
btw:
throw something_at_asc ("kröte");
Es ist einfach schon viel zu spät..

Bei Verwunderung und Fragezeichen ob dieses Satzes bitte kontaktiere deinen Artzt, oder ...
-
Hmmm, ja stimmt...
Okay, wie sieht es denn dann hiermit aus?#include "stdafx.h" #include "stdio.h" #include <iostream> using namespace std; typedef signed long int32; // 32 Bit mit Vorzeichen struct T3DVECF { public: float x; float y; float z; }; struct TRIANGLE { public: int32 i; int32 j; int32 k; }; bool LoadSTL (const char* fnm, T3DVECF *& P, int32 &n, TRIANGLE *& T, int32 &m) { P = new T3DVECF[2]; T = new TRIANGLE[3]; P[0].x = 1; P[1].x = 2; T[0].i = 100; n = 1000; m = 200; return true; } int _tmain() { const char* fnm; fnm = ""; T3DVECF* P = 0; TRIANGLE* T = 0; int32 n; int32 m; LoadSTL(fnm, P, n, T, m); std::cout << "P[0].x = " << P[0].x << "\n"; std::cout << "P[1].x = " << P[1].x << "\n"; std::cout << "T[0].i = " << T[0].i << "\n"; std::cout << "n = " << n << "\n\n"; delete[] P; delete[] T; std::cin.get(); return 0; }Zumindest läuft es und mir werden die richtigen Werte ausgegeben. Oder ist hier trotzdem noch was falsch? Wie sieht es mit dem Bereinigen des Speichers aus? P und T werden ja in der Funktion allokiert, aber ich kann sie ja erst am Ende des Programms wieder löschen. Ist das so richtig?
Vielen Dank für die Hinweise!
-
Direkt falsch ist das nicht. Es ist nur nicht besonders schön. Da würde ich dir eher zur Benutzung von smart Pointern raten. (siehe boost).
Das Problem ist einfach, dass im Falle einer anderen Terminierung des Programmes, als durch normalen Fluss, z.B durch eine exception der Speicher nicht freigeben wird, wenn der Code nicht erreicht wird. Das passiert dir mit smart Pointer nicht.