Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Daten von C nach PAS und PAS nach C ... (https://www.delphipraxis.net/215578-daten-von-c-nach-pas-und-pas-nach-c.html)

paule32.jk 30. Jul 2024 16:08

Daten von C nach PAS und PAS nach C ...
 
Hallo,
ich bin noch in der Überlegungsphase, wie man am besten Daten von Delphi nach GNU C austauscht und wieder zurück...
Wie wir ja alle wissen, ist es ja nicht so einfach, Delphi Klassen in C++ zu verwenden.

Mein Ansatz wäre:
- innerhalb einer C++ DLL eine Funktion schaffen, die, wenn in Delphi foo := TFoo.Create; erreicht wird:
in C++ extern "C" void* set_new_class("foo") { ... } zu schreiben,
wobei dann der C Funktions-Parameter "foo", in eine C++ std::map gespeichert wird, um so zum einen den
Namen der Referenz sowie den Referenz-Pointer zu speicher

- mit einer weiteren C Funktion: void* get_class_ptr("foo") { ... } den Pointer holen um dann auf Objekte
der Klasse zuzugreifen.

Aber wie kann man das erreichen, wenn man keine Interfaces oder COM+ nutzen möchte ?
Muss da ein Anwendungs-Server und ein auf dem Server abgestimmter Client herhalten ?

wie könnte man das lösen ?

Incocnito 30. Jul 2024 16:18

AW: Daten von C nach PAS und PAS nach C ...
 
Moin moin!

Wenn wir Daten von einer Programmiersprache in eine andere schieben wollen, gehen wir über Json.
Geht das bei C++ nicht auch? Bei Delphi geht das recht easy.
Du musst dann nur die Datenstruktur, also die Klassen passend anlegen.
... Nur falls du einfach auf den offensichtlichen, einfachen Weg nciht gekommen bist,
so wie mir das ständig geht. ;-)

Liebe Grüße
Incocnito

paule32.jk 30. Jul 2024 17:08

AW: Daten von C nach PAS und PAS nach C ...
 
ja stümmt, ich dummerjen.

brauch ich aber trotzdem eine Einsprungsadresse aus der DLL,
die ich mit GetProcAddr holen könnte.

Danke für den Tipp

himitsu 30. Jul 2024 17:15

AW: Daten von C nach PAS und PAS nach C ...
 
* innerhalb eines Prozesses? (EXE und DLLs)
* innerhalb des Systems? (zwischen Anwendungen, bzw. beim OLE ein OutOfProzess-Server ... z.B. fremde EXE oder DLL in der dllhost.exe)
* zu einem anderem System (VM, Intranet oder sonstwo im Internet)


IPC
Records/Structs
...

dummzeuch 30. Jul 2024 17:38

AW: Daten von C nach PAS und PAS nach C ...
 
Ich habe (unter anderem) darüber auf den letzten Forentagen einen Vortrag gehalten. Auf der Seite gibt es auch Sourcecode-Auszüge.

paule32.jk 30. Jul 2024 18:48

AW: Daten von C nach PAS und PAS nach C ...
 
ah mich deuchtet was ...
der Thomas hat im Quellcode GetProcAddr Pointer verwendet.

jetzt fällt mir gerade ein, das ja der Constructor - egal welche Sprache, ja eine Objekt-Referenz zurückliefert, die dann durchgereicht werden kann...
nicht schlecht sprach Herr Specht.
Danke

himitsu 30. Jul 2024 19:01

AW: Daten von C nach PAS und PAS nach C ...
 
Nein, egal ob zu C++ oder sonstwas ... Klassen-Instanzen zu übergeben macht man einfach nicht.

Bei Packages wird die TypeInfo/Klassendeklaration und die Prozeduren gemeinsam genutzt.
Bei DLL besitzt JEDER seine eigene Kopie und die kann sich beim Kompilieren minimal/extremst unterscheiden, selbst wenn auf beiden Seiten das gleiche Delphi zum Einsatz kam.

Nicht nur die getrennten TypeInfo/RTTI ... ohne ein Shared-Memory geht sowieso nix.

Selbst mit viel einfacheren Strukturen gab es hier ganz böse Probleme.
https://www.delphipraxis.net/213736-...-fuer-neu.html

paule32.jk 30. Jul 2024 19:05

AW: Daten von C nach PAS und PAS nach C ...
 
und wenn man nur die Funktionnamen zu einer importierten Funktion weiterleitet,
und dann intern die Pointer handhabt ... ?

hmmm, doppelt nachgedacht, macht das Sinn...

Incocnito 31. Jul 2024 09:05

AW: Daten von C nach PAS und PAS nach C ...
 
Keine Chance, echt Objekte (außer jetzt die serialisierte Form, wie bei Json) rüber zu reichen ist nicht zu empfehlen.
Ja, es kann sein, dass es klappt, aber liegt beim Kunden die alte DLL, die Exe wurde aber mit einem anderen Compilerflag
compiliert und er nutzt die neue EXE bekommt er lustig Fehlermeldungen und Speicherfehler, die keiner vernünftig
lokalisieren kann.
Lass dich nicht zu verleiten, das so zu tun, nur weil es bei dir beim ersten Test klappt
(oder weil du heute sagst "DLL und EXE werden immer zusammen ausgeliefert").
Das wird dich in falscher Sicherheit wiegen!

himitsu 31. Jul 2024 10:39

AW: Daten von C nach PAS und PAS nach C ...
 
Wenn, dann maximal als Pointer und im C wirklich nichts damit machen, außer durchreichen (auf delphiseite ein Cast ... Cast, nicht Pointer auf Variable)

dummzeuch 31. Jul 2024 10:49

AW: Daten von C nach PAS und PAS nach C ...
 
Zitat:

Zitat von paule32.jk (Beitrag 1539379)
ah mich deuchtet was ...
der Thomas hat im Quellcode GetProcAddr Pointer verwendet.

jetzt fällt mir gerade ein, das ja der Constructor - egal welche Sprache, ja eine Objekt-Referenz zurückliefert, die dann durchgereicht werden kann...
nicht schlecht sprach Herr Specht.
Danke

Ich reiche keine Pointer auf Instanzen durch sondern nur ein Handle, welches einem Index in ein Array von Instanzen entspricht. Schau Dir den im Vortrag genannten Link auf ein Beispiel bei Embarcadero an, da steht, wie das funktioniert.

Wichtig: Eine C++-Instanz wird automatisch freigegeben, wenn es keine Referenz mehr darauf gibt. Deshalb muss man diese Istanz im Array speichern, bevor die Funktion in der DLL, die die Instanz erzeugt hat, verlassen wird. (Zumindest habe ich das gerade so in Erinnerung, es ist schon wieder eine ganze Weile her, dass ich mich mit dem Kram beschäftigt habe.)

himitsu 31. Jul 2024 11:26

AW: Daten von C nach PAS und PAS nach C ...
 
OK, Objekt vom C++, welches im Delphi durchgereicht wird.

Ober Objekt von Delphi, welches im C++ durchgereicht wird.
Joar, falls dort ARC aktiv wäre, dann hätte man ebenfalls diesen Spaß mit der Referenzzählung. :freak:

paule32.jk 31. Jul 2024 11:33

AW: Daten von C nach PAS und PAS nach C ...
 
Hallo Thomas,
ja, das stimmt.
Speicher(variablen) wird solange gehalten bis sie nicht mehr genutzt werden.
Es gibt zwei Arten, wie Variablen gehalten werden:

Heap => innerhalb einer Prozedur/Funktion gültig (lokaler Scope), und:
Stack => überlebt, wenn die Prozedur/Funktion verlassen wird.

Das mit den Array war ja auch so in meine Richtung...
Eine in C++ verwendete std::map< std::string, void* > Insntanzen;

Dann braucht man nur noch in etwa sowas machen: instanzen["foo"] = 0xcafebabe;
und die map im globalen Scope belassen, dann überleben die Pointer.

Aber ich habe gerade ein anderes Problem:

hier verwende ich einen Delphi-PChar:
Delphi-Quellcode:
{$APPTYPE CONSOLE}
program Project1;

uses Windows;

type
  TMyFunction = procedure(s: PChar); cdecl;

var
  DLLHandle: HMODULE;
  MyFunction: TMyFunction;

begin
  DLLHandle := LoadLibrary('foo.dll');
  if DLLHandle = 0 then
  begin
    MessageBox(0,'Error: DLL could not be loaded.','Error',0);
    ExitProcess(1);
  end;
  try
    @MyFunction := GetProcAddress(DLLHandle, 'TestFunction');
    if @MyFunction = nil then
    begin
      MessageBox(0, 'Error: TestFunction not found in DLL.', 'Error', 0);
      ExitProcess(1);
    end;
    MyFunction(PChar('jukel'));
  finally
      FreeLibrary(DLLHandle);
      ExitProcess(0);
  end;
end.
und hier nur einen 0-terminierten C char *:

Code:
#include <windows.h>
#include <iostream>

#ifdef _WIN64
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT
#endif

extern "C" {
DLL_EXPORT void TestFunction(char* func) {
    std::cout << "Func: " << func << std::endl;
}
};
beide Image-Dateien sind im 64-Modus kompiliert.
Aber ich erhalte als Ergebnis (auf der Konsole):

Func: j

Sinspin 31. Jul 2024 13:29

AW: Daten von C nach PAS und PAS nach C ...
 
Was ist denn char in C++ und PChar in Delphi für ein Typ? Haben die die gleiche Anzahl von Bytes je Zeichen?

himitsu 31. Jul 2024 13:56

AW: Daten von C nach PAS und PAS nach C ...
 
der C++ Char ist Byte :stupid:

(wir könnten es aber auch als AnsiChar ansehn, ohne P)

paule32.jk 31. Jul 2024 15:26

AW: Daten von C nach PAS und PAS nach C ...
 
Hallo,

ich habe gerade hier nachgesehen: Delphi PChar -> C++

dort wird PChar als PWideChar deklariert.

Ich hatte das noch von früheren Delphies und C plus'sers in Erinnerung, das jeweils unter Delphi und C/C++ ein PChar einen char* entsprach - also beide die gleiche Bitbreite hatten. In modernen Sprachen, habe ich gerade mitbekommen, das PChar unter C++ tatsächlich 8-Bit entsprechen und null-terminiert sind.
Aber in modernen Anwendungen PWideChar - also mit 16-Byte pro Zeichen gearbeitet wird, was dann bedeutet, das 2 Zeichen verarbeitet werden. Nach dem eigentlichen Zeichen, auch bei UTF-8, ein null-Byte hinten drann kommt, und ebenfalls null-terminiert wird - aber halt mit null-null-Byte.

Jetzt fällt mir auch ein, das Windows 11 und frühere Versionen schon auf 16-Bit umgestellt haben, so dass in modernen Compilern aus utf-8, das eine Mixtur aus 8 und 16-Bit ist, generell auf 16-Bit breite arbeiten.

Bin halt nicht mehr der jüngste - und nicht mehr ub du dätde.
Schande über mein Haupt - und verzeiht mir :roll:

Der Tipp von Sinspin war also goldwert - Danke !

Edit:
Die C++ Version des getesteten Testes ist dann so lauffähig:

Code:
#include <windows.h>
#include <iostream>

#ifdef _WIN64
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT
#endif

extern "C" {
DLL_EXPORT void TestFunction(wchar_t* func) {   
    std::wcout << "Func: " << func << std::endl;
}
};

himitsu 31. Jul 2024 15:32

AW: Daten von C nach PAS und PAS nach C ...
 
Das Delphi-Char ist ein generischer Typ, also compilerabhängig und stellt aktuell einen Alias des WideChar dar. (vor 2009 war es ein AnsiChar)

Das C++-char ist ein statischer Typ, also ist immer 1 Byte groß, ähnlich dem uchar, entgegen dem wchar mit 2 Byte.




Und genau so ein Mist, ist es, weswegen das WinMD an vielen Stellen total verbuggt ist.
https://www.delphipraxis.net/214473-...vor-winmd.html

paule32.jk 31. Jul 2024 15:52

AW: Daten von C nach PAS und PAS nach C ...
 
Hallo,

- schaltet sich damit Microsoft Windows aus, oder:
- ist das ein Problem beim Delphi-Entwickler ?

wenn lezteres, ist das:
- ein Problem der CE Versionen, oder:
- ein Problem aller Versionen ?

wenn lezteres, warum will der Delphi-Enwickler für eine Pro-Version: 1.234 Euro (im Angebot) ?
wenn lezteres, sind denen die russischen Leute abgehauen, weil sie gegen den kapitalistischen Westen ein Dorn im Auge sind ?

Fragen über Fragen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:38 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