![]() |
habe DLL aber nur C++ und VB Beispiele
Hallo zusammen
ich habe eine DLL die ich verwenden will. Der Hersteller der das vertreibt unterstützt aber nur VB und C++. Also sind in seiner Dokumentation auch nur VB und C++ Beispiele dabei. Ich will aber Delphi verwenden also hab ich mal angefangen die C++ Header Files bzw. die entprechende .Bas Datei in Delphi zu übersetzen. Das geht so weit auch. Und einige wenige funktionen kann ich auch schon beutzen (vor allem die ohne Parameter Übeergabe) C++ KMErrorCode EXPORTFCN KMTCPRefreshDevices( void ); // funktioniert in delphi KMErrorCode EXPORTFCN KMTCPGetNumDevices( LPUINT16 lpnNumDevices ); // das auch delphi Function KMTCPRefreshDevices (): Long; cdecl; external 'KmApi32.DLL'; Function KMTCPGetNumDevices (lpnNumDevices : pWord): Long; cdecl; external 'KmApi32.DLL'; aber bei folgender Funktion geht nix C++ /* TCPIP Server Control access functions */ KMErrorCode EXPORTFCN KMTCPGetDeviceInformation(char *lpszNameArray[], char *lpszAddressArray[], char *lpszSNArray[], UINT16 DIPArray[], int nNumDevices ); wie muß ich das hier machen?? es wird nachher in C++ verwendet wie folgt /*------------------------------------------------------------------------*/ unsigned short NumberDevices = 0; /* Force the API to look for devices on the network */ KMTCPRefreshDevices(); /* Get the number of devices found on serial and/or Ethernet */ KMTCPGetNumDevices(&NumberDevices); /* Initialize the array to retrieve all device names, */ /* serial numbers, and IP addresses */ char **NameArray= new char*[NumberDevices]; char **IPArray = new char*[NumberDevices]; char **SNArray = new char*[NumberDevices]; UINT16 *DIPArray = new UINT16[NumberDevices]; for(int j=0;j<NumberDevices;j++) { NameArray[j]=new char[MAX_TCP_NM_LENGTH]; IPArray[j]=new char[MAX_TCP_IP_LENGTH]; SNArray[j]=new char[MAX_TCP_SN_LENGTH]; } /* Retrieve the device information */ KMTCPGetDeviceInformation(NameArray, IPArray, SNArray, DIPArray, NumberDevices); /*------------------------------------------------------------------------*/ und wie muß ich das dan verwenden?? ich hoffe mir kann jemand helfen Gruß Stefan |
Re: habe DLL aber nur C++ und VB Beispiele
Hi Stefan,
diese char-Pointer-Arrays sind in Delphi folgendermaßen zu deklarieren:
Delphi-Quellcode:
und das UINT16-Array so:
TDynPCharArray = array of PChar;
Delphi-Quellcode:
also sähe die Methode-Deklaration folgendermaßen aus:
TDynWordArray = array of Word;
Delphi-Quellcode:
MfG
function KMTCPGetDeviceInformation(NameArray, AddressArray, SNArray: TDynPCharArray; DIPArray: TDynWordArray; NumDevices: Integer); cdecl; external 'KmApi32.dll';
Stevie P.S. Code-Tags würden deinen Beitrag etwas besser lesbar machen. |
Re: habe DLL aber nur C++ und VB Beispiele
Sorry Stevie, komplett falsch. "array of" ist nie zu einem C Typ kompatibel.
Delphi-Quellcode:
Entweder gibt nNumDevices die Laenge der Arrays von PChars bzw UINT16 an oder die Arrays werden durch einen PChar = nil abgeschlossen.
type
PPChar = ^PChar; UINT16 = Word; PUInt16 = ^UINT16; function KMTCPGetDeviceInformation(lpszNameArray: PPChar; lpszAddressArray: PPChar; lpszSNArray: PPChar; DIPArray: PUINT16; nNumDevices: Integer): KMErrorCode; cdecl; |
Re: habe DLL aber nur C++ und VB Beispiele
Zitat:
|
Re: habe DLL aber nur C++ und VB Beispiele
danke robert
weil mit dem Vorschlag von Stevie hatte ich so meine Probleme aber mit den PPChar hab ich auch meine Probleme wie soll ich das denn initialisieren? habs mal so versucht
Code:
aber so geht das nicht aber ich weiß auch gar nicht wie ich das überhaupt anpacken soll mit dem init?
err := KMInitialize;
NumDevices :=0; refresh := KMTCPRefreshDevices(); getNum := KMTCPGetNumDevices(@NumDevices); if getNum = 0 then begin erg := 'Controllers Found '+IntToStr(NumDevices); for lLoop := 0 to NumDevices-1 do begin sNames^[lLoop] := ' '; sIP^[lLoop] := ' '; sSerStr^[lLoop] := ' '; end; err := KMTCPGetDeviceInformation(sNames, sIp, sSerStr, sDipArray, NumDevices); end; ist das nicht sowas wie eine pointer liste? ratloser Gruß Stefan |
Re: habe DLL aber nur C++ und VB Beispiele
Man sollte den Namen der Funktion lesen. Es werden offensichtlich eine Menge Puffer ausgefuellt.
Entsprechend ist der Parameter ein "Buffers: array [0..WASAUCHIMMER] of PChar" und jeder PChar muss seinerseits einen Puffer alloziiert haben. Vermutlich steht in der Dokumentation wie lang so ein Name maximal sein kann. Der Aufruf ist dann "KMTCPGetDeviceInformation(@Buffers[0], ...)" Alternativ kann es sein das in Buffers nur Zeiger auf die intern vorgehaltenen Namen abgelegt werden. Dann ist es nicht noetig die Elemente zu alloziieren, sondern man sollte dann die Elemente mit nil belegen. Da kann aber nur die Dokumentation weiterhelfen. |
Re: habe DLL aber nur C++ und VB Beispiele
Zitat:
Ich habe zuerst C gelernt und bin froh darueber. Im Gegensatz zum Durchschnitts-Pascal-Programmierer lernt man naemlich was ein Zeiger ist. Gerade habe ich mal wieder eine besonders lustige Variablendeklaration in C anbringen koennen. extern const volatile unsigned long int * const SomePointer; Wer diese durchaus sinnvolle Deklaration entraetseln kann der gewinnt meine Hochachtung. |
Re: habe DLL aber nur C++ und VB Beispiele
Danke einstweilenwerde das morgen gleich mal probieren.
Gruß Stefan |
Re: habe DLL aber nur C++ und VB Beispiele
Zitat:
Was du da machst, ist einen Zeiger zu deklarieren, bei dem weder der Wert des Zeigers noch der Wert des Datums, auf der der Zeiger zeigt, innerhalb des Programm verändert werden kann, wohl aber von außen. Sinn machen würde das ganze, wenn du einen Wert, der z.B. per Interrupt gesetzt wurde, in deinem Programm verfügbar machen wilsst und dabei 100% sichergehen musst (naja, 100%ige Sicherheit hast du wohl nie), dass der Wert nicht verfälscht wird. Aber wozu man das braucht, fällt mir auch nicht ein :? |
Re: habe DLL aber nur C++ und VB Beispiele
Hochachtung!
Brauchen kann man das natuerlich. Wie waere es mit einer Interrupt Tabelle in einem Mikrocontroller? |
Re: habe DLL aber nur C++ und VB Beispiele
Zitat:
Nun, ich hab bisher leider nur mit hardwareabstrahierter Programmierung auf PCs Erfahrung und leider nicht mit µCs :? Aber OK; jetzt wirklich zurück zum Thema! |
Re: habe DLL aber nur C++ und VB Beispiele
Ich hab da immer noch meine Probleme!
Mach ich die Initialisierung richtig?
Code:
Beim Compilieren kommt kein Fehler zurückvar nBuff : array of PChar; ipBuff : array of PChar; SerStrBuff : array of PChar; DipArrayBuff : array of PUint16; name : Array[0..MAX_TCP_NM_LENGTH] of pChar; ip: Array[0..MAX_TCP_IP_LENGTH] of pChar; ser: Array[0..MAX_TCP_SN_LENGTH] of pChar; ppName, ppIp, ppSer : pPchar; begin err := KMInitialize; NumDevices :=0; refresh := KMTCPRefreshDevices(); getNum := KMTCPGetNumDevices(@NumDevices); SetLength(nBuff, NumDevices); SetLength(ipBuff, NumDevices); SetLength(serStrBuff, NumDevices); SetLength(DipArrayBuff, NumDevices); for lLoop := 0 to NumDevices-1 do begin for c:= 0 to MAX_TCP_NM_LENGTH do name[c] := new(pChar); nBuff[lLoop] := name[0]; for c:= 0 to MAX_TCP_IP_LENGTH do ip[c] := new(pChar); ipBuff[lLoop] := ip[0]; for c:= 0 to MAX_TCP_SN_LENGTH do ser[c] := new(pChar); serStrBuff[lLoop] := ser[0]; DipArrayBuff[lLoop] := new(PUint16); end; ppName := @nBuff[0]; ppIp := @ipBuff[0]; ppSer := @serStrBuff[0]; if getNum = 0 then begin err := KMTCPGetDeviceInformation(ppName, ppIp, ppSer, DipArrayBuff[0], NumDevices); end; Beim debugen ist mir aber aufgefallen, daß in nBuff[0] keine Adresse steht! Obwohl es da eigentlich eine Geben müßte. Wieder ratloser Gruß Stefan |
Re: habe DLL aber nur C++ und VB Beispiele
Und es geht doch. Ich war schon ganz dicht an der Lösung.
Mein Fehler war ein var in der Funktions deklaration.
Code:
ohne das var gings dann plötzlich!
Function KMTCPGetDeviceInformation(var lpszNameArray,lpszAddressArray,lpszSNArray: PPChar ;DIPArray: PUInt16 ;nNumDevices :long): KMErrorCode; cdecl; external 'KmApi32.DLL';
Danke an alle Beteiligten Erleichterter Gruß Stefan |
Re: habe DLL aber nur C++ und VB Beispiele
Das "var" hatte ich auch nicht geschrieben.
Die Initialisierungen sind noch Murks. Schmeiss alles was sich auf array of bezieht weg. Also nBuff, die lLoop-Schleife und die SetLength Aufrufe. Offensichtlich liefert die Funktion in name usw PChars ab. ppName usw wird auch nicht gebraucht. Direkt @name[0] usw als Parameter benutzen. Die Funktion braucht ein array von PChar's, die auch wirklich im Speicher vorhanden sind. "name" und Konsorten erfuellt das, denn das Array ist auf dem Stack vorhanden. Die Deklaration von KMTCPGetNumDevices mit "var" statt Zeiger umschreiben, dann kann man KMTCPGetNumDevices(NumDevices); benutzen. |
Re: habe DLL aber nur C++ und VB Beispiele
kurze Frage am Rande:
PChar = Pointer auf Char PPChar = Pointer auf PChar = Pointer auf Pointer auf Char??? Hat das n speziellen grund das ihr das so macht? Greetz Boombuler |
Re: habe DLL aber nur C++ und VB Beispiele
Vielleicht ist es Murks aber es funktioniert.
Zitat:
aber was ich nicht verstehe ist @name[0] ist doch der Zeiger auf nur einen Namen. Was ist wenn ich mehrere devices habe NumDevices>1 ? Deshalb habe ich das mit den dynamischen arrays ja so gemacht, daß NumDevices variabel sein kann. Brauche ich dann nicht genau soviel Pointer auf die unterscheidlichen name[lLoop] wie es devices gibt? enspricht das dann nicht so in etwa dem was auch in C++ gemacht wurde
Code:
oder wie sollte ich das namens array (also nicht name[0]..) anders initialisieren.
/* serial numbers, and IP addresses */
char **NameArray= new char*[NumberDevices]; char **IPArray = new char*[NumberDevices]; char **SNArray = new char*[NumberDevices]; UINT16 *DIPArray = new UINT16[NumberDevices]; for(int j=0;j<NumberDevices;j++) { NameArray[j]=new char[MAX_TCP_NM_LENGTH]; IPArray[j]=new char[MAX_TCP_IP_LENGTH]; SNArray[j]=new char[MAX_TCP_SN_LENGTH];
Code:
das ist natürlich murks und müll, das hab ich auch gleich selbst gelöscht und dann
ppName := @nBuff[0];
ppIp := @ipBuff[0]; ppSer := @serStrBuff[0];
Code:
direkt aufgerufen.
KMTCPGetDeviceInformation(@nBuff[0], @ipBuff[0], @serStrBuff[0], DipArrayBuff[0], NumDevices);
Verwirrter Gruß Stefan |
Re: habe DLL aber nur C++ und VB Beispiele
ja das hat es. C++ ruft das halt auch so auf.
Musst Dir mal bei meiner 1. Frage den C++ code anschauen wie da vor dem Funtionsauruf die arrays initialisiert werden.
Code:
und das muß in Delphi dann halt auch so ähnlich genacht werden damit man die Funktion benutzen kann.
char **NameArray= new char*[NumberDevices];
char **IPArray = new char*[NumberDevices]; char **SNArray = new char*[NumberDevices]; Aber der Oberblicker bin ich da auch nicht. |
Re: habe DLL aber nur C++ und VB Beispiele
Die C Deklaration lautet "char *name[]". Das ist praktisch das selbe wie "char **name".
Die feinen Unterschiede wollen wir hier nicht waelzen. Also lautet die Pascal Deklaration korrekt PPChar eben ein Zeiger auf einen Zeiger auf Char. C kennt nur call by value. Call by reference wird genau durch "Zeiger auf" repraesentiert. Das ist das was Pascal bei var-Parametern auch macht. Ueblicherweise gilt bei der Uebergabe eines Arrays in C das der Zeiger auf das erste Element des Arrays uebergeben wird. Die Groesse des Arrays muss in einem gesonderten Parameter uebergeben werden. Alternativ wird der letzte Zeiger des Arrays auf nil gesetzt um das Ende anzuzeigen. "char *name[]" ist also ein Array von PChars. |
Re: habe DLL aber nur C++ und VB Beispiele
das ist ja alles schön und gut und richtig. Aber wie soll ich denn dann
"char *name[]" initialisieren wenn nicht so wie ich es gemacht habe. Möglich, daß ich mich auch bloss blöd anstelle aber ich hab keine Ahnung wie ich es anders machen könnte. Aber es ist auch möglich, daß ich dadurch wie ich es gemacht habe mein nächstes Problem erzeugt habe, nämlich wie im Thread "immer noch Stress mit DLL Aufruf" beschrieben der Absturz beim Zugreifen auf meine eingelesenen PPChar arrays. Immer noch einigermassen ratloser Gruß Stefan |
Re: habe DLL aber nur C++ und VB Beispiele
Hallo Stefan,
solltest du nicht weiterkommen, dann kannst du mir die VB-Deklarationen schicken. Ich helfe dir dann beim Übersetzen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz