Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Parameterübergabe per Zeiger auf Referenz

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
21.10.2008, 15:15 Uhr
stevieda



Hallo zusammen,

Ich habe folgendes Problem (habe die Suchfunktion und die FAQs bereits genutzt aber ich komme trotzdem einfach nicht weiter):
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.


C++:
//#######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


C++:
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!
--
Gruß,
Stevie
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
21.10.2008, 16:52 Uhr
zac



Moment, das ist eine Referenz auf einen Zeiger, umgekehrt gibts das gar nicht, da eine Referenz immer gültig sein muss.
Du übergibst der Funktion also ganz normal die Pointer auf die einzelnen Strukturen...

In deinem Programm sähe so ein Funktionsaufruf also etwa so aus:


Code:
T3DVECF* P = new T3DVECF[ARRAY_LENGTH];
LoadSTL(someconstcharpointer,&P[ARRAY_INDEX],someint,sometrianglepointer,someint2);



Wenn ich dich richtig verstanden habe...

Ach, und nochwas:
Wenn du 64-bit-Plattformen unterstützen willst, aber unbedingt int32 brauchst, dann funktioniert das int32 so nicht. Eventuell ist es eine gute Idee <stdint.h> einzubinden und die dort definierte Form von int32_t nach int32 zu typedef'n.
--
mov eax,0f9h
push 2
push 2
mov edx,esp
int 2eh

Dieser Post wurde am 21.10.2008 um 16:56 Uhr von zac editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
22.10.2008, 11:19 Uhr
stevieda



Hallo zac,

Also wenn ich das richtig verstanden habe... könnte mein Code dann folgendermaßen aussehen?


C++:
#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!
--
Gruß,
Stevie
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
22.10.2008, 11:49 Uhr
Oliver
S2-Pixelgeneral



Zitat:
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.



Ist es denn notwendig, dass das Array erst erstellt werden muss und dann der Funktion übergeben wird (die es dann "erweitert", was nicht so ohne weiteres möglich ist) oder soll dir die Funktion ein Array zurückgeben und du sollst ihr nur einen Zeiger geben, die sie dann auf die Adresse des Arrays setzt?

Für mich sieht das jetzt eher nach letzterem aus und dann wäre es wohl so:


C++:
int _tmain()
{
    const char* fnm;
    T3DVECF* P = 0; // einfach mal mit 0 initialisieren, nicht unbedingt nötig
    TRIANGLE* T = 0;
    int n;
    int m;
    
    LoadSTL(fnm, P, n, T, m); // P und T wird von der Funktion gesetzt

    std::cout << P[1].x << "\n\n";

    delete[] P;
    delete[] T;

    std::cin.get();
    return 0;
}



Auf jedenfall ist das kein schöner Stil, wenn du Speicher freigeben musst, der intern von einer Funktion allokiert wurde, aber so wie ich das verstanden habe, kannst du wohl nichts dafür.
--
Demokratie ist die Diktatur der Mehrheit.

www.siedler25.org/ ( Siedler2 - Remake )
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
22.10.2008, 14:17 Uhr
stevieda



Vielen Dank schon einmal für die Hilfe. Das hat mir wirklich geholfen.
Was das Freigeben des Speichers betrifft: kann man das denn auch anders machen?

Ich habe erfahren, dass in der DLL dieser externen Firma auch eine weitere Funktion eben zum Freigeben des Speichers zur Verfügung steht:


C++:
dll_intern bool _cdecl FreeMEM (T3DVECF   * P, TRIANGLE  * T);


Würde ich die dann auch so ansprechen (s.u.)?

C++:
FreeMEM (P, T);

--
Gruß,
Stevie
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
22.10.2008, 14:46 Uhr
Oliver
S2-Pixelgeneral


Nunja, anscheinend ist das hier eine C-DLL, aber in C++ regelt man sowas in der Regel mit irgendwelchen Objekten, deren Destruktor (also wo der Speicher dann freigegeben wird) automatisch aufgerufen wird, hier wäre ein std::vector z.B. geeignet, aber das brauch dich ja jetzt nicht zu interessieren.

Ja, die müsste so aufgerufen werden.
--
Demokratie ist die Diktatur der Mehrheit.

www.siedler25.org/ ( Siedler2 - Remake )
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
22.10.2008, 18:01 Uhr
zac



Mal angenommen, die Funktion würde das nicht allokieren (wovon ich mit der Information dass es auch FreeMEM gibt aber ausgehen würde, aber dazu solltest du vllt die Dokumentation der DLL angucken, wenns sowas gibt):
Es ist möglich, dass der meckert, weil der Pointer da ja nicht als const-referenz übergeben wird und der den Wert in der Funktion ja ändern können will - probier mal z.B. folgendes:


Code:
const char* fnm;
T3DVECF* P = new T3DVECF[4];
TRIANGLE* T = new TRIANGLE[4];
T3DVECF* Pmember = &P[2];
TRIANGLE* Tmember = &T[1];
int n,m;

LoadSTL(fnm,Pmember,n,Tmember,m);




@Oliver:
Warum soll eine C-DLL-Funktion Referenzparameter übergeben bekommen? Wäre die in C geschrieben müsste die Funktion doch: LoadSTL(const char* fnm, T3DVECF** P, ...) aussehen...
Wobei das natürlich sein kann dass der einfach einen C++-Header dafür gebaut hat... Referenz und Pointer sollten sich ja für die DLL-Funktion selbst (in Asm) nicht unterscheiden...
--
mov eax,0f9h
push 2
push 2
mov edx,esp
int 2eh

Dieser Post wurde am 22.10.2008 um 18:04 Uhr von zac editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: