Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   dll einbinden / Pointer Probleme (https://www.delphipraxis.net/167766-dll-einbinden-pointer-probleme.html)

Assarbad 17. Apr 2012 18:32

AW: dll einbinden / Pointer Probleme
 
Zitat:

Zitat von himitsu (Beitrag 1162355)
Und wo steht dort was von einem String/PChar?
Sieht eher nach einem HRESULT/Cardinal aus.
Aber irgendwo wird ja COM_RETURN_OK ja deklariert sein.

Außer bei der Originalvariante (als Delphi-Referenz durchsuchenstring) und bei DeddyH's Versuch steht da nix von Delphi-Referenz durchsuchenPChar. In der C-Variante fehlen Linkage, Aufrufkonvention und Rückgabewert komplett.

Meine Glaskugel hat auch Urlaub.

Zitat:

Zitat von shmia (Beitrag 1162358)
Ist das evtl. nur ein Wrapper für TCP/IP?
Ich hab schon erlebt, dass manche versuchen eine DLL für die serielle Schnittstelle anzusteuern, obwohl man mit einer Delphi Komponente viel besser dran wäre.

Die Befürchtung halte ich für sehr berechtigt.

Pow3rus3r 18. Apr 2012 10:06

AW: dll einbinden / Pointer Probleme
 
Wow, danke für die Beteiligung!

Konkret geht es um folgendes: Ich habe eine Hardware, die über Ethernet angesteuert werden soll. Der Hardwarehersteller hat dazu eine dll zur Verfügung gestellt, welche die Funktionen für Kommunikationsaufbau, Abbau und Datenübertragung enthält. Ich versuche nun eine Kommunikation mit dem Steuergerät herzustellen (Funktion COM_TcpOpen in der DLL). Die Funktion ist in der Onlinehilfe des Hardwareherstellers wie folgt dokumentiert:
Code:
EXPORTDLL COM_RETURN EBEL_API COM_TcpOpen ( COM_Handle *  handle,
  const char *  ipAddress,
  u16  port
 )  

Generates a new PC HW interface. To communicate with a hardware over Ethernet.

Parameters:
handle = Pointer to a handle representing the interface instance. Will be filled by this function.
ipAddress = IP Address of the target.
port = Port number used to communicate with the target.

Returns:
COM_RETURN_OK Function executed successfully.
COM_RETURN_Failed The function failed to create a new handle.
Hier die Codeausschnitte aus dem c++ Beispielprogramm vom Hardwarehersteller:
Typedef:
Code:
/// \brief Defines a handle to a PC->Hardware communication object.
typedef void* COM_Handle;
COM_Return Definition:
Code:
/// \brief Return values used by the interface functions. This type provides information about an error. A zero value means no error occured.
typedef enum COM_RETURNtag
{
    COM_RETURN_OK = 0,               ///< Function executed successfully.
    COM_RETURN_Failed,               ///< Function execution failed.
    COM_RETURN_InvalidHandle,         ///< The handle parameter was NULL or not a matching PC HW interface handle.
    COM_RETURN_InvalidParameter,      ///< One of the parameter was invalid.
    COM_RETURN_NullPointer,            ///< One of the paramter was a NULL pointer but should point to a stucture or variable.
    COM_RETURN_Timeout,               ///< The hardware was not responding or not reachable.
    COM_RETURN_NotSupported,         ///< The command requested was not supported by the application on the hardware.
    COM_RETURN_AlreadyRunning,         ///< The function / application is already running.
    COM_RETURN_Locked               ///< The function can not be executed while the HW/SW/region is locked.
} COM_RETURN;
COM_TcpOpen Aufruf in C++:
Code:
//---------------------------------------------------------------------------
// Example of an implementation of a COM_TcpOpen call
//---------------------------------------------------------------------------

void CHwComTestGuiDlg::OnBnClickedOpentcp()
{
    CString str;

    UpdateData();   // Update the member variables with the values in the text fields.
#ifdef BLUETOOTH_INTERFACE
    //Disable bluetooth "Open" and "Close" buttons
    CButton *tcpBTHOpenClose;
    tcpBTHOpenClose = (CButton*) GetDlgItem(IDC_CBUTTON_OPEN);
    tcpBTHOpenClose->EnableWindow(FALSE);
    tcpBTHOpenClose = (CButton*) GetDlgItem(IDC_CBUTTON_CLOSE);
    tcpBTHOpenClose->EnableWindow(FALSE);
#endif   
    COM_RETURN ret = COM_TcpOpen(&m_hCom,m_ipAddress.GetBuffer(),m_nPort);      // Call the function
    PrintErrorInfos("COM_TcpOpen",ret);         // Visualize the result
}
Der komplette C++ Quellcode ist wohl leider zu groß, um ihn hier zu posten. Falls aber noch weitere Infos nötig sind, poste ich diese gerne.

Der Entwickler der dll hat mir eben noch geschrieben, dass er sich mit Delphi leider nicht auskennt, aber er davon ausgeht, dass ich vergessen habe, die Zeigeradresse beim Funktionsaufruf mit anzugeben. Nun bin ich aber leider selber nicht der Delphi-Pro und wüsste auf Anhieb auch nicht, ob und wie ich die Adresse übergeben kann.

himitsu 18. Apr 2012 10:43

AW: dll einbinden / Pointer Probleme
 
In Delphi sind ENUM standardmäßig so klein wie möglich.

In C sind sie standardmäßig (glaub ich) so groß wie ein Register.
(früher Integer, aber weil irgendein Arsch meinte Integer/Cardinal einfriehren zu müssen NativeInt/NativeUInt)


Also COM_Return entweder als NativeUInt
oder als ENUM, aber mit MinimumEnumSize = RegisterSize.

Die Strings als AnsiString/AnsiChar/PAnsiChar.

COM_Handle als
Delphi-Quellcode:
var COM_Handle: THandle;
.

Tipp: Das iparray als AnsiString ... läßt sich dann leichter verwenden. :wink:


Und siehst du ... gleich alle wichtigen Infos rausrücken und schon geht es schneller.

Pow3rus3r 18. Apr 2012 11:32

AW: dll einbinden / Pointer Probleme
 
Mit THandle hatte ich es ja schon versucht, jedoch ohne Erfolg.

Der DLL Entwickler schrieb mir ja, dass man der Funktion die Zeigeradresse mit übergeben soll... nur wie macht man das in Delphi?

Im Moment bekomme ich wieder die Fehlermeldung, dass das Lesen auf dem Speicherbereich x nicht möglich ist.

himitsu 18. Apr 2012 11:55

AW: dll einbinden / Pointer Probleme
 
Delphi-Quellcode:
type PHandle = ^THandle;

var MyHandle;
Delphi-Quellcode:
var COM_Handle: THandle
(
Delphi-Quellcode:
MyHandle
) entspricht dem
Delphi-Quellcode:
COM_Handle: PHandle
(
Delphi-Quellcode:
@MyHandle
).

Pow3rus3r 18. Apr 2012 13:16

AW: dll einbinden / Pointer Probleme
 
Blöde Frage: Wo bringe ich die Befehle in meinem Code unter? Kommt hinter das "var MyHandle;" noch irgendwas? Delphi meckert da rum, dass es ein Komma oder Semikolon erwartet.

Pow3rus3r 24. Apr 2012 07:21

AW: dll einbinden / Pointer Probleme
 
So, der Verbindungsaufbau funktioniert nun endlich. Es lag an einem falschen Datentyp bei der IP Adresse. Dort habe ich nun einen Ansistring verwendet.

Nun stehe ich aber schon vor dem nächsten Problem. In der DLL gibt es eine Funktion, die folgende Struktur füllt und dann über einen Pointer ausgelesen werden soll:

typedef struct COM_Version
{
u08 Major;
u08 Minor;
u08 Patch;
u08 Build;
} COM_Version;


u08 steht dabei für unsigned char.
Welchen Datentyp kann ich hier in Delphi verwenden, um diese Daten auszulesen? Ich denke, es muss in irgendeiner Weise ein Array verwendet werden, oder? Mit Datentyp char funktioniert es in Delphi leider nicht (Zugriffsverletzung).

DeddyH 24. Apr 2012 07:56

AW: dll einbinden / Pointer Probleme
 
Versuch einmal:
Delphi-Quellcode:
type
  TCOM_Version = packed record
    Major,
    Minor,
    Patch,
    Build: Byte;
  end;
Ggf. musst Du die Felder in umgekehrter Reihenfolge deklarieren, kommt darauf an, wie sie befüllt werden.

Bummi 24. Apr 2012 07:58

AW: dll einbinden / Pointer Probleme
 
Wie wäre es mit einem Array of Byte?

Pow3rus3r 24. Apr 2012 09:34

AW: dll einbinden / Pointer Probleme
 
ich habe die type Definition nun in Delphi so übernommen - aber es tat sich leider nichts. Immernoch Zugriffsverletzung.

Der Code sieht nun wie folgt aus (Typedeinition nicht mit inbegriffen):
Delphi-Quellcode:
function COM_GetVersionReq(var zeiger:Pointer; version:TCOM_Version): NativeUInt ; cdecl; external 'HwCom.dll';

procedure TForm1.btngetversionClick(Sender: TObject);
var
  typevers: TCOM_Version;
begin
  return := COM_GetVersionReq(zeiger, typevers);
end;
Die public Variable Zeiger wurde schon von einer anderen Funktion (COM_TcpOpen) gefüllt.

Typevers istd er Rückgabewert, den die Funktion liefern soll. Müsste ich hier evtl. wieder einen Pointer auf die Variable "typevers" setzen, um den Wert von der Funktion bekommen zu können?


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:20 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz