AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Delphi Unit (Language Binding) für eigene C-Lib - Umsetzung

Delphi Unit (Language Binding) für eigene C-Lib - Umsetzung

Ein Thema von Zacherl · begonnen am 9. Sep 2017 · letzter Beitrag vom 11. Sep 2017
Antwort Antwort
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#1

AW: Delphi Header für C-Lib - Umsetzung

  Alt 9. Sep 2017, 17:47
Hey hey, erstmal danke für deine Antwort!

Ich glaube allerdings wir reden ein wenig aneinander vorbei Meine Frage bezieht sich auf eine ganz konkrete Library (die ich in C geschrieben habe) und nicht die C-Runtime Lib (habe mal versucht den Titel etwas eindeutiger zu gestalten). Einige Ansätze aus deiner Antwort kann ich allerdings trotzdem übernehmen. Das Verwenden von .inc Files ist auf jeden Fall eine gute Idee, mit der ich mein C-Header-Konzept beibehalten könnte, trotzdem aber auf Delphi Seite nur eine Unit hätte.

Vermutlich werde ich so vorgehen, dass ich eine Low Level Implementierung unter dem Namen MyLib.API.pas oder einfach nur MyLib.pas erstelle, welche die kompletten Funktionen und Datentypen der C-Lib bereitstellt. Zusätzlich kann ich dann noch die Units MyLib.ModuleA.pas , MyLib.ModuleB.pas und MyLib.ModuleC.pas erstellen, welche dann jeweils die Kapselung der 3 Module in richtigen (Wrapper-)Klassen bereitstellt.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.384 Beiträge
 
Delphi 12 Athens
 
#2

AW: Delphi Unit (Language Binding) für eigene C-Lib - Umsetzung

  Alt 9. Sep 2017, 20:18
Jupp, im Prinzip stimme ich mit dem Überein, was schon mein Vorredner sagte.


Theoretisch kann man Methden von Klassen auch direkt external mit Prozeduren verlinken,

aber in der Prakis hat es sich bewährt erstmal die API möglichst 1:1 nach Pascal zu übersetzen,
somit kann diese Schnittstelle erstmal genauso verwendet werden, wie es die Dokumentation und die vielen C-Beispiele zeigen (wenn man eine bekannte C-Lib übersetzt).
Allerdings passe ich die Namen der Parameter öfters mal an (mehr Delphi-Style und entferne Prefixe).
Auch Typen passe ich dem Delphi-Style an, so lange es möglich ist, wie z.B. Integer statt INT oder VAR statt Pointer.
Sogar Const-String statt PChar ist oftmals möglich, bei IN-Parametern, aber lohnt sich nur, wenn sowas bei allen Prozeduren möglich ist, da mit sich möglichst alles an einen "einheitlichen" Style hält.

Wenn direkt als Klasse, dann aber möglichst nah an der originalen API. (Benamung)

Wie gesagt, so kann man die API "auch" im Original-Style verwenden
und vorallem ist es so einfacher später neue Verionen der API einfließen zu lassen.



Falls ich Zeit hab, dann würde ich das Ganze dann nochmal in "schönere" Klassen/Interfaces mit "verständlicheren" Methodennamen kapseln (Wrapper),
bzw. kleinere spezialisiertere, minimalistische und einfache Komponenten.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 9. Sep 2017 um 20:28 Uhr)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.175 Beiträge
 
Delphi 12 Athens
 
#3

AW: Delphi Unit (Language Binding) für eigene C-Lib - Umsetzung

  Alt 10. Sep 2017, 06:22
Ich würde es auch eher 1:1 umsetzen, allein schon wegen der Wartbarkeit und lesbarkeit.

Allerhöchstens wenn A, B, C trivial sind würde ich das in eine Unit nehmen, aber das wäre meiner Meinung nach etwas schlechter Stil, weil A, B, C sicherlich auch verschiedene Aufgaben haben.
Diese Aufgabentrennung sollte man am Besten auch in Delphi 1:1 abbilden.

Rollo
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

AW: Delphi Unit (Language Binding) für eigene C-Lib - Umsetzung

  Alt 10. Sep 2017, 15:10
in der Prakis hat es sich bewährt erstmal die API möglichst 1:1 nach Pascal zu übersetzen
Alles klar

Allerdings passe ich die Namen der Parameter öfters mal an (mehr Delphi-Style und entferne Prefixe).
Auch Typen passe ich dem Delphi-Style an, so lange es möglich ist, wie z.B. Integer statt INT oder VAR statt Pointer.
Perfekt. Das habe ich auch bereits so gemacht. Typen mit T geprefixt, CamelCase Schreibweise und var bzw. const für Pointer. Zusätzlich habe ich für einige Enums noch Helper Methoden wie z.b. ToString implementiert (dafür hat die C-Lib jeweils eine exportierte Funktion).

Ich würde es auch eher 1:1 umsetzen, allein schon wegen der Wartbarkeit und lesbarkeit.

Allerhöchstens wenn A, B, C trivial sind würde ich das in eine Unit nehmen, aber das wäre meiner Meinung nach etwas schlechter Stil, weil A, B, C sicherlich auch verschiedene Aufgaben haben.
Diese Aufgabentrennung sollte man am Besten auch in Delphi 1:1 abbilden.
Ich werde jetzt wohl den Kompromiss wählen und für jeden C-Header eine .inc Datei erstellen, die ich dann später in einer einzelnen API Unit zusammenfasse. Dann habe ich die Sachen ordentlich getrennt und man muss hinterher trotzdem nich 15 (Sub-)Units einbinden, damit alle Typen der Lib zur Verfügung stehen. Für die Kapselung in Klassen erstelle ich dann nochmal 3 weitere Units mit den entsprechenden Modulen A, B und C. Dann muss der User unter Delphi immer die API Unit verwenden und je nach gewünschtem Modulen noch die entsprechende Unit mit den Wrapperklassen einbinden.

Danke euch allen!

Noch irgendwelche Tipps zum Lösen von Namenskonflikten die auftreten, wenn ich zusätzliche Wrapperklassen schreibe? Habe in C ja meine Context-Structs wie z.b. MyDecoder , die ich dann erstmal 1:1 nach Delphi als TMyDecoder = record umsetze. Die Wrapperklasse kann ich jetzt natürlich nicht auch TMyDecoder nennen. Hier lieben den Namen der Wrapperklasse mutieren (TMyDecoderWrapper oder sowas) statt Den des Records? Oder doch liebe den Record umbenennen in z.b. TMyDecoderStruct und dafür die High-Level Klasse bei TMyDecoder belassen?

Achso und würdet ihr Klassen, Typen, Records, Konstanten, etc. mit dem Namen der Lib prefixen? Mangels Namespaces mache ich das eigentlich ganz gerne in Delphi (auch wenn man Mehrdeutigkeiten natürlich mit explizitem Angeben der Unit lösen kann - was aber auch irgendwie nichts Ganzes und Halbes ist).
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#5

AW: Delphi Unit (Language Binding) für eigene C-Lib - Umsetzung

  Alt 10. Sep 2017, 16:22
Zur Namensgebung und als Alternative, wo man in C das simpel per Groß/Klein-Schreibung macht:

TMyTool verwende ich in Delphi nur für "echte" Klassen/Objekte, also alles was man per CreateAufruf erzeugen muss
RMyTool verwende ich in Delphi für Records, also C Structs, welche sich auch statisch ohne "Create" nutzen lassen
PMyTool definiere ich immer zusammen mit RMyTool als typisierten Pointer von RMyTool

Mit Operatoren und Propertys für Records also "R..." habe seit D2007 sehr gute Erfahrungen mit allen weiteren Delphi Varianten.
Ich nutze insbesondere die "default" Property oft als typisiertes virtual Array/List... funktioniert seit D2007 super und ersetzt mit die doofen TList<XY> Generics die zwar schön einfach zu tippen sind, aber bei mir schlicht zu langsam und zu instabil sind.


Präfixe:
- auch wenn OldScool: ich mache es auch heute noch
- allgemeines wie ein GetValue, ein UpdateStorage oder UpdateGUI sind aus meiner Sicht "ohne Kontext" sehr schlecht im Code zu verstehen... daher lieber mylibGetValue, mylibUpdateXXX
- ich ziehe das trotz der paar Zeichen Zusatztiparbeit so durch, hat den positiven neben Effekt, das fremde in der Anwendung auch stets sofort sehen&wissen in woher das kommt und bei bedarf dort finden, wozu das ist und was es macht

Wer nur mit allgemeingültigen Interfaces ala "WriteData" arbeiten will, der soll es tun und kann es sich selbst HighLevel so definieren. Ich bevorzuge bei LowLevel und ExternalModule einer kurze 1:1 PräfixVariante, welche bei mir auch so schon im C Source vorhanden ist

Geändert von mensch72 (10. Sep 2017 um 16:35 Uhr)
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Delphi Unit (Language Binding) für eigene C-Lib - Umsetzung

  Alt 11. Sep 2017, 06:18
Zu a:

Ich würde sie erstmal 1 zu 1 umsetzen und dann darauf aufbauend eine entsprechende Klassenhirarchie aufbauen.

Eine Funktions-Lib in eine Klassenhirarchie zu packen, nur damits OOP-Konform ist, macht keinen Sinn und erzeugt i.d.R. nur Overhead.


Zu b:

Hier würd ich zu 1. tendieren. Damit erleichtert man die Orientierung, sowohl im Source, als auch ggf. in der Dokumentation.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#7

AW: Delphi Unit (Language Binding) für eigene C-Lib - Umsetzung

  Alt 11. Sep 2017, 16:28
TMyTool verwende ich in Delphi nur für "echte" Klassen/Objekte, also alles was man per CreateAufruf erzeugen muss
RMyTool verwende ich in Delphi für Records, also C Structs, welche sich auch statisch ohne "Create" nutzen lassen
PMyTool definiere ich immer zusammen mit RMyTool als typisierten Pointer von RMyTool
Ansich eine gute Konvention, allerdings nicht ganz konform mit dem Pascal Style Guide, welcher das T Prefix für sämtliche Typen vorsieht. Allerdings sehe ich hier zumindest bezüglich der CamelCase Bezeichner sogar explizit eine Ausnahme für Header Translations. Muss ich mich mal umsehen, wie die breite Masse das hier so handhabt. In den JEDI API Headern meine ich mich erinnern zu können, dass Typen immer erst mit ihrem originalen Namen (ohne T Prefix und vollständig in Capslock) deklariert wurden und danach nochmal ein Alias mit T Prefix und CamelCase angelegt wurde.

Präfixe: - auch wenn OldScool: ich mache es auch heute noch
Schön zu sehen, dass ich hier nicht alleine stehe

Ich würde sie erstmal 1 zu 1 umsetzen und dann darauf aufbauend eine entsprechende Klassenhirarchie aufbauen.

Eine Funktions-Lib in eine Klassenhirarchie zu packen, nur damits OOP-Konform ist, macht keinen Sinn und erzeugt i.d.R. nur Overhead.
Habe jetzt mal mit der 1:1 Übersetzung angefangen. Die Sache mit den *.inc Files ist leider doch nicht so wirklich praktikabel, weshalb ich die 1:1 Übersetzung vorerst komplett in eine Unit packe. Bezüglich der Funktions-Libs hast du recht. In meinem Falle beziehen sich die Funktionen aber immer auf eines der der 3 Module (ModuleAInit, ModuleAMachWas, ModuleASetThis, ModuleAGetThat , etc), sind also perfekt in Klassen zusammenfassbar.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:12 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