Forums Neueste Beiträge
 

Einbindung C-DLL / Datentypen?

09/05/2008 - 15:52 von Martin Meyer | Report spam
Hallo NG,

ich habe ein Problem bei der Nutzbarmachung einer FKT aus einer C-DLL. in
VB6. Das reale Beispiel ist etwas komplexer - ich reduziere das Problem
mal auf das Wesentlichste.
Die FKT erwartet neben ein paar lngWerten im wesentlichen ein Zeiger auf
ein Personenobjekt. Dies hàlt ein paar Stammdaten und ein Zeiger auf ein
Array von Adress-Objekten. (Eine Person kann mehrere Adressen haben /
gehabt haben)
Die benötigten Typen-. und die Funktions-deklarationen habe ich mir aus
dem Header-File geklaubt, das mir in die Hànde gefallen war.

// die beiden Objekte
typedef struct {
LPSTR lpszOrt;
LPSTR lpszPLZ;
LPSTR lpStrasse;
} AdressDescriptor, FAR * lpAdressDescriptor;

typedef struct {
LPTSTR lpszName;
LPTSTR lpszVorname;
LPTSTR lpszGebDatum;
FLAGS flFlagGeschlecht;
lpAdressDescriptor lpAdressen; // Zeiger Adress-Struct-Array
} OBJ_Person, FAR *OBJ_Person;

// die exportierte FKT
typedef ULONG FAR PASCAL MachEs(
ULONG ulParameter,
OBJ_Person lpPerson,
FLAGS flFlags
);

In VB umgesetzt habe ich das so:

' die beiden Objekte aus den structs
Type AdressDescriptor
lpszOrt As String
lpszPLZ As String
lpStrasse As String
End Type

Type OBJ_Person
lpszName As String
lpszVorname As String
lpszGebDatum As String
flFlagGeschlecht As Long
lpAdressen() As AdressDescriptor ' <-- geht das so?
End Type

' Die exportierte FKT
Declare Function MachEs Lib "Die.DLL" (ByVal ulParameter&, _
lpPerson As OBJ_Person, ByVal Flags&) As Long

Wenn ich die FKT gemàß folgender Sub teste, also ohne Benutzung
desAdressobjekt-Arrays, dann tut's die Funktion. Natürlich fehlen mir im
Ergebnis die Adressen der Person (es wurden ja auch keine zugeordnet).

Public Sub fummel()
Dim lngRes As Long
Dim oPerson As OBJ_Person
Dim oAdresse(1) As AdressDescriptor

' With oAdresse(0)
' .lpszOrt = "Entenhausen" & vbNullString
' .lpszPLZ = "E-54321" & vbNullString
' .lpStrasse = "Am Teich 7" & vbNullString
' End With

With oPerson
.lpszName = "Gans" & vbNullString
.lpszVorname = "Gustav" & vbNullString
.lpszGebDatum = "07/22/1952" & vbNullString
.flFlagGeschlecht = 1
.lpAdressen = oAdresse
End With

lngRes = MachEs(8, oPerson, 0)
Debug.Print lngRes
End Sub

Sobald aber das Füllen eines Adressobjektes einkommentiert wird, versagt
die FKT. Wahrscheinlich habe ich was bei der Umsetzung der beiden
benutzerdefinierten Datentypen falsch gemacht(?).
So ganz falsch kann die Umsetzung aber auch nicht sein, immerhin geht's
ja mit dem Personenobjekt, wenn keine Adressobjekte zugefügt werden.

Kann man so ein aus 2 Structs zusammengesetztes Datenobjekt überhaupt von
VB an eine C-DLL übergeben - wie?

Es geht mir weniger um eine Lösung für das spezielle Problem, sondern
eher darum, wie und ob man solche Strukturen übergeben kann.

TIA & Gruß,
Martin

Bei Antworten per eMail bitte an die Reply-To Adresse senden.
Oder der From-Adresse den String "nospam_" voranstellen.
eMails an die unmodifizierte From-Adresse werden ungelesen geloescht.
 

Lesen sie die antworten

#1 Thorsten Albers
09/05/2008 - 16:42 | Warnen spam
Martin Meyer schrieb im Beitrag
...
Type OBJ_Person
lpszName As String
lpszVorname As String
lpszGebDatum As String
flFlagGeschlecht As Long
lpAdressen() As AdressDescriptor ' <-- geht das so?
End Type



Nein, das geht nicht. In C ist ein Array-Zeiger ein Zeiger auf das 1.
Element des Arrays. In VB ist ein Array-Zeiger ein Zeiger auf eine
SAFEARRAY-Struktur, die wiederum einen Zeiger auf das 1. Element des Arrays
enthàlt.
Dieses Problem ist bei der Übergabe von VB an C lösbar, indem man das
entsprechende Struktur-Feld in VB "As Long" deklariert und mit "... VarPtr(MyArray(LBound(MyArray)))" die Adresse des 1. Elementes im Array
'manuell' eintràgt.
Allerdings besteht in Deinem Code jedoch offensichtlich ein anderes
Problem: Wenn ich das richtig sehe, gibt es zwar einen Zeiger auf das Array
mit den Adressen, aber es wird nirgendwo die Anzahl der Adressen angegeben,
die der DLL in dem Array der Struktur übergeben werden! Ohne eine
entsprechende Abànderung des DLL-Codes ist dieses Problem nicht lösbar!

Kann man so ein aus 2 Structs zusammengesetztes Datenobjekt überhaupt von
VB an eine C-DLL übergeben - wie?



Ja, natürlich - und wenn man (wie hier teilweise erforderlich) mit VarPtr()
und CopyMemory()/RtlMoveMemory() arbeiten muß.

-
Thorsten Albers albers(a)uni-freiburg.de
-

Ähnliche fragen