Übergabe einer Struktur aus C++

stevieda

Grünschnabel
Hallo zusammen,

ich habe eine DLL in C++, die eine Struktur enthält und diese an VB übergeben soll.

DLL-Code:

struct EDGE {
double a;
double b;
} edge1;

EDGE _stdcall transfer(double Zahl1, double Zahl2)
{
edge1.a = Zahl1 + 1;
edge1.b = Zahl2 + 3;
return edge1;
}
Das Beispiel ist sehr einfach, aber mir geht es wirklich nur darum zu verstehen, wie ich aus C++ eine Struktur übergeben kann.

Der VB-Code sieht folgendermaßen aus:

Public Structure myStruct
Dim x As Double
Dim y As Double
End Structure

Public Declare Function transfer Lib "Strukturuebergabe.dll" (ByVal Zahl1 As Double _
, ByVal Zahl2 As Double) As myStruct
sub irgendwas()
Dim Kante As myStruct

Kante = transfer(10, 15)
MsgBox(Kante.x)
end sub

Kann mir da irgendjemand bei helfen? Bin für jede Anregung dankbar.
Grüße,
Stevie
 
Zuletzt bearbeitet:
Mit welchem VB arbeitest Du? Dies ist das Forum für VB6 (wie die Überschrift schon sagt), und da gibt es das Schlüsselwort "Public Structure" nicht, dort wäre es "Public Type".

Ansonsten schreibst Du leider auch nicht, wo denn genau nun Dein Problem liegt.

Grüsse
 
Hallo Ronald,

entschuldige, Du hast natürlich Recht. Also ich arbeite sowohl mit VBA (VB 6) als auch VB 8 (2005). Insofern ist mir die Version für die Erklärung egal. Aber Du hast natürlich auch Recht, dass aus

Public Structure myStruct
Dim x As Double
Dim y As Double
End Structure

dann folgendes wird:


Public Type myStruct
Dim x As Double
Dim y As Double
End Type

Meine Frage zielte generell darauf ab, wie man eine Struktur aus einer C++-DLL an VB übergeben kann. Da dies ein Programmiersprachen-übergreifendes Problem ist, könnte man jetzt sagen: bitte wende Dich an das C++-Forum bzw. umgekehrt. Aber vielleicht kann mir ja hier jemand helfen.

Mein Problem ist, dass ich nicht weiß, wie ich in VB eine Struktur aus meiner C++-DLL empfange. So, wie ich es in meinem Code gemacht habe, funktioniert es leider nicht.
Ich habe aber noch mal ein wenig getestet und folgendes funktioniert:

/---------C++-Code -----------------------------------
struct STRUKTUR {
long x;
long y;
} *ByRefValue;

long _stdcall transfer(struct STRUKTUR *ByRefValue)
{

(*ByRefValue).x += 1;
(*ByRefValue).y += 1;

return((*ByRefValue).x + (*ByRefValue).y);
}
/----------Ende C++-Code ----------------------------

'-----------VB-Code--------------------------------------
Public Declare Function transfer Lib "Strukturuebergabe.dll" (ByRef ByRefValue As STRUKTUR) As Long

Public Type STRUKTUR
x As Long
y As Long
End Type

Private mystruct As STRUKTUR

Sub Main()

Dim result As Long

mystruct.x = 45
mystruct.y = 2

result = transfer(mystruct)
MsgBox ("" & mystruct.x & " + " & mystruct.y & " = " & result)

End Sub
'-----------Ende VB-Code----------------------------------

Dies funktioniert. Jetzt möchte ich jedoch nicht eine Zahl (Addition von x und y) sondern die gesamte Struktur an VB zurückgeben. Und genau das ist mein Problem. Kann mir da jemand helfen?
Vielen Dank im voraus und nochmals Entschuldigung für den holprigen Einstieg und die fehlenden Informationen.

Grüße,
Stevie
 
Meine letzten C-Tätigkeiten liegen zwar Ewigkeiten zurück.

Jedoch fällt mir gleich auf, dass Deine C++-Funktion im VB als "Long" deklariert ist (dann kann logischerweise nur eine einzige Zahl, jedoch keine Struktur zurückkommen). Im C++ müsste der Funktion meiner Meinung nach auch gesagt werden, dass sie eine Struktur zurück geben soll.

In dieser Richtung solltest Du mal forschen.

Darüber hinaus würde ich bei DLL-Übergaben grundsätzlich die Werte ByVal übergeben und zurück holen. Die Speicherbehandlung von C und Basic ist unterschiedlich. By reference greift C++ direkt auf Speicheradressen des Rechners zu. Falls Dir dabei Fehler unterlaufen, können die Folgen außerordentlich schwerwiegend sein.

Grüsse
ronaldh
 
Mal dumm gefragt: Wieso machst du es nicht wie folgt:

Visual Basic:
Public Declare Function Transfer Lib "blablab.dll" (ByVal Zahl1 As Double, ByVal Zahl2 As Double, ByRef refStruct As STRUKTUR) As Long

Du übergibst wie bisher in den ersten zwei Argumenten deine zwei Zahlen, holst das Ergebnis aber als Referenz zurück, und den Rückgabewert der Funktion (As Long) kannst du dann als Boolean-Wert benutzen, ob die Funktion fehlerfrei durchgelaufen ist.

Ich erinner mich dunkel daran, dass ich in einem Buch mal gelesen habe, dass z.B. Struktur-Rückgabewerte aus Win-API-Calls immer nur als Referenz-Parameter ablaufen.

btw: Aufpassen mit den Datentypen! Ein Long in VB6 ist 32-Bit lang, entspricht also dem int in C++
 
@Ronald:

Danke für den Hinweis, aber das untere Beispiel soll ja auch tatsächlich nur einen Long zurückgeben. Das war quasi die Vorstufe zu dem oberen Beispiel. Im oberen Code habe ich ja angegeben, dass eine Struktur zurückgegeben werden soll.
Strukturen müssen für C++ ByRef übergeben werden. ByVal funktioniert hier nicht.

@Zvoni:

Aaah, das hört sich schon mal interessant an! Werde ich gleich mal austesten.
Das mit ByRef ist völlig richtig. Bei Strukturen ist das so.

Das mit den unterschiedlichen Datentypen ist mir auch schon aufgefallen. Hatte mich schon gewundert, warum bei einer simplen Addition von zwei Integer in C++ auf einmal ein falscher Wert in VB ankommt. Wenn ich zwei Integer in C++ addiere (kommen auch als Integer aus VB) und die Summe als Long an VB zurückgebe und VB einen Long erwartet, dann stimmt das Ergebnis nicht. Was ist daran falsch? Muss ich dann die beiden Zahlen als Long an C++ übergeben?

Vielen Dank für beide Beiträge
Gruß,
Stevie
 
Zurück