DllExecuteCall() - zu füllendes Array als Parameter

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
FrankL
Rookie
Rookie
Beiträge: 7
Registriert: Fr, 04. Sep 2009 8:38

DllExecuteCall() - zu füllendes Array als Parameter

Beitrag von FrankL »

Hallo,

ich versuche an eine DLL ein Array (aUserNames ) zu übergeben. Dieses soll befüllt werden. Man muss wohl wie in C erst einmal den Speicher reservieren.

Code: Alles auswählen

LOCAL aUserNames := Array(ADS_MAX_INFO)  
...
DllExecuteCall( scDllGetMgGetUserNames, nHandle, cFileName, aUserNames , @nArrayLen )
Allerdings bekomme ich dann den Fehler:
dllExecuteCall
Parameter hat falschen Typ
Mache ich das nicht, so ist das Array nach dem Aufruf nicht vom Typ Array.
Wie macht man das prinzipiell richtig? Das muss doch gehen?!

Gruß,
Frank
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Re: DllExecuteCall() - zu füllendes Array als Parameter

Beitrag von Günter Beyes »

Hallo Frank,

zunächst einmal herzlich willkommen hier im Forum!

Und -- das geht auch.

Ein C-Array entspricht in Xbase++ einem aus mehreren gleichartigen Teilen -- hier sind es Strukturen -- zusammengesetzten String.
Du erzeugst also für das Array einen leeren String der Länge Elementezahl * Strukturgröße und übergibst ihn per Referenz an die C-Funktion.

ADS_MGMT_USER_INFO belegt 212 Bytes.

Code: Alles auswählen

typedef struct
{
UNSIGNED8 aucUserName[ADS_MAX_USER_NAME];			// Länge 50 Bytes
UNSIGNED16 usConnNumber;                                  // Länge 2 Bytes
UNSIGNED8 aucAuthUserName[ADS_MAX_USER_NAME];		// Länge 50 Bytes
UNSIGNED8 aucAddress[ADS_MAX_ADDRESS_SIZE];			// Länge 30 Bytes
UNSIGNED8 aucOSUserLoginName[ADS_MAX_USER_NAME];		// Länge 50 Bytes
UNSIGNED8 aucTSAddress[ADS_MAX_ADDRESS_SIZE];			// Länge 30 Bytes
} ADS_MGMT_USER_INFO;
Das ist aus ace.h, Advantage Client Engine Version 8.1
http://devzone.advantagedatabase.com/dz ... Platform=6

Code: Alles auswählen

nStructureSize := 212
nArrayLen        := ADS_MAX_INFO

cUserArray := space(  nArrayLen * nStructureSize  )

rc := DllExecuteCall( scDllGetMgGetUserNames,  nHandle, cFileName,;
                    @cUserArray , @nArrayLen,  @nStructureSize )
Wenn der Aufruf erfolgreich war, enthält nArrayLen jetzt die Anzahl der gültigen Einträge in cUserArray,
und nStructureSize die tatsächliche Strukturgröße.

Damit kannst du cUserArray in seine Bestandteiile zerlegen und diese schließlich in ein Xbase++-Array schreiben.

Code: Alles auswählen

if rc == 0  // AE_SUCCESS
   nIndex1 := 1
   for i := 1 to nArrayLen
       // Eine ADS_MGMT_USER_INFO-Struktur  herausziehen
       cTemp  := substr( cUserArray, nIndex1, nStructureSize  )
       nIndex1 += nStructureSize

       // Elemente aus der Struktur herausziehen
       nIndex2 := 1
       cComputerName := GetString( cTemp, @nIndex2, ADS_MAX_USER_NAME )
       nConnection := GetWord(  cTemp, @nIndex2, 2 )
       cDDUserName := GetString( cTemp, @nIndex2, ADS_MAX_USER_NAME )
       cAddress := GetString( cTemp, @nIndex2, ADS_MAX_ADDRESS_SIZE )
       cOSUserName := GetString( cTemp, @nIndex2, ADS_MAX_USER_NAME )
       cTSAddress := GetString( cTemp, @nIndex2, ADS_MAX_ADDRESS_SIZE )

       aadd( aUsers, {cComputerName, nConnection, cDDUserName, cAddress, cOSUserName, cTSAddress  } )
   next 
endif
mit den Hilfsfunktionen

Code: Alles auswählen

function GetString( cBuffer, nIndex, nLength )
local cString
local nPos

cString := substr( cBuffer, nIndex, nLength )
nIndex += nLength

// der String ist nullterminiert
nPos := at( chr(0), cString )
if nPos > 0
   cString := left( cString, nPos-1 )
endif

return cString

function GetWord( cBuffer, nIndex, nLength )

local nWord

nWord := Bin2W( substr( cBuffer, nIndex, nLength ) )
nIndex += nLength

return nWord
Gruß,
Günter
FrankL
Rookie
Rookie
Beiträge: 7
Registriert: Fr, 04. Sep 2009 8:38

Re: DllExecuteCall() - zu füllendes Array als Parameter

Beitrag von FrankL »

Hallo Günter,

Danke. Das hat super funktioniert. Ich hatte das auch mit BAP probiert. Ich konnte die Struktur auch erstellen, bin aber dann daran gescheitert eine Array von Strukturen zu machen.
Aber so funktionierts auch super.

Gruß,
Frank
Antworten