![]() |
Wie ein array of record von C# dll mit COM an Delphi übergeben?
Hallo,
ich bin am verzeifeln. Ich möchte in Delphi eine Methode von einer C# DLL aufrufen und einen array of record in Delphi bekommen. Das Record könnte so aussehen:
Delphi-Quellcode:
Dazu Ich habe einfach in Visual Studio 2019 eine "Class Library (.NET Framework)" Project erstellt und eine DLL mit einer einzigen Methode erstellt. Diese DLL lade ich einfach in Komponenten importieren->Typenbibliothek rein und erhalte eine TLB Unit in Delphi. Wenn die Funktionsparameter nur aus String oder Integer bestehen funktioniert es auch wunderbar. Doch wie kann ich von C# aus array of struct/record als Parameter übergeben?
RMEDIA = packed record
Name: String; ID: Integer; end; Auf C# Seite habe ich mal folgendes versucht:
Code:
Wenn ich diese erstellte DLL in Delphi über die Komponente installieren->Typenbibliothek importierenreinlade erhalte folgende Methode:
using System;
using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; namespace DelphiTest { public class CrossDLL { public struct RMEDIA { public String Name; public int ID; } public string HelloWorldArray(out RMEDIA[] structArray, ref int arraySize) { arraySize = 2; // Create an array of MyStruct structArray = new RMEDIA[arraySize]; // Populate the array with data for (int i = 0; i < arraySize; i++) { structArray[i].ID = i + 1; structArray[i].Name = "Hallo"; } return $""; } } }
Delphi-Quellcode:
Wenn ich folgendes versuche:
function HelloWorldArray(out structArray: PSafeArray; var arraySize: Integer): WideString;
Delphi-Quellcode:
bekomme ich gleich folgende eine Fehlermeldung:
procedure TForm1.Button2Click(Sender: TObject);
var CrossDLL: TCrossDLL; Items: PSafeArray; arraySize: Integer; begin CrossDLL :=TCrossDLL.Create(self); CrossDLL.HelloWorldArray(Items, arraySize); end;
Code:
Hat jemand einen Ansatz für mich? :gruebel: :gruebel:
---------------------------
Project1 --------------------------- Altes Format oder ungültige Typbibliothek. (Ausnahme von HRESULT: 0x80028019 (TYPE_E_UNSUPFORMAT)) --------------------------- OK --------------------------- |
AW: Wie ein array of record von C# dll mit COM an Delphi übergeben?
Mir geht es im Moment nicht gut, deshalb nur kurz:
Ich verwende das NuGet Paket DllExport und erstelle damit nativ exportierte Funktionen. Die DLL kann man dann in Delphi einfach mit LoadLibrary laden. Ich habe darum herum dann ein Framework gebaut, mit dem ich C#-Interfaces generisch aus Delphi heraus abrufen oder umgekehrt in der C#-DLL Interfaces aus der Delphi-Hostanwendung abrufen kann. Auf diese Weise kann ich auch z.B. direkt generische Listen in beiden Richtungen als Parameter verwenden. Aber für dich reichen ja die nativen Funktionen vermutlich schon. Nächste Woche kann ich dazu bei Bedarf auch mehr schreiben. Den entsprechenden Quelltext kann ich aber leider nicht zeigen. |
AW: Wie ein array of record von C# dll mit COM an Delphi übergeben?
Was willst du im C# mit diesem Record machen?
Wenn nur lesen, dann kann String als PChar angesehen werden (also char* und vielleicht auch char[] bis 2007 und wchar ab Delphi 2009) Überschreiben einzelner Chars ginge zwar auch, aber nur sicher, wenn vorher ![]() und die länge Ändern bedingt einen Zugriff auf den Delphi-Speichermanager, also grundsätzlich somit erstmal NEIN, für Schreibzugriffe. Warum benutzt du denn keinen WideString? Das ist eine Kapselung des BSTR vom C++, also von ![]() |
AW: Wie ein array of record von C# dll mit COM an Delphi übergeben?
@himitsu: zunächst möchte die Record Arrays in Delphi nur mal einlesen können. Wie schon gesagt funktioniert die Sache mit einfachen Typen wie String und Integer ohne Probleme. Ich weiß halt nur nicht wie ich ein Array of Record von C# an Delphi weitergebe, so dass der Delphi Typenbibliothek Import einwandfrei klappt.
Der Hintergrund ist, dass es vom Hersteller nur eine C# DLL existiert. Und auch die ganze Doku für C# ausgelegt ist. Da ich es aber in Delphi vewenden möchte, habe ich mir gedacht, dass ich dafür eine C# COM Wrapper DLL schreibe, die ich einfach über die Delphi Typenbibliothek importiere. |
AW: Wie ein array of record von C# dll mit COM an Delphi übergeben?
Ach andersrum :oops:
in Delphi gefüllt -> in C# lesen in C# gefüllt -> in Delphi lesen Jetzt müsste man wissen, wie im C# deren "String" intern aufgebaut ist. Ich würde mal vermuten es ist ein PPChar ... ein PChar-kompatibler Typ, der in einem Objekt verpackt wurde. :freak: Hilft aber nur, wenn du manuell die Konvertierung/Übergabe machst. Vermutete einfachste Lösung: benutze das, was im C# einem BSTR (aka WideString) entspricht. Oder eben einen OleVariant. Man kann sich auf das Minimum konzentrieren und muß auf der anderen Seite etwas Gleichwertiges, oder zumindest Kompatibles finden. PChar ist ein Zeiger auf Chars, die durch #0 terminiert (abgeschlossen) werden. Die "LongStrings" von Delphi (String, AnsiString, UnicocdeString) sind intern kompatibel mit einem PChar. -> die Verwaltungsdaten liegen rückwertig vor dem internen Zeiger (der auf das erste Char zeigt) und hinter dem letzten Char befinden sich implizit zwei #0. Drum lässt sich ein String problemlos in einen PChar casten. Der ShortString (hieß gaaaaanz früher mal "string") ist ein Record, bzw. statisches CharArray, wo der Char[0] das Längenbyte darstellt. (drum fangen im Delphi auch alle Strings auch mit 1 an :wink:) Der "OLE-String" WideString basiert intern auf einem BSTR und benutzt die APIs SysAllocString/SysReAllocString/SysFreeString der oleauto.h bzw. OleAut32.dll. |
AW: Wie ein array of record von C# dll mit COM an Delphi übergeben?
@jaenicke: vielen Dank für den Hinweis mit dem DllExport. Wie so oft hast du mir ja schon weitergeholfen! :thumb: :thumb: Ich habe zwar nicht DllExport Package verwendet, sondern das
![]() ![]() ![]() Was dein Angebot bzgl. deinen Ansatz mit DllExport betrifft, so wäre ich sehr interessiert. Natürlich erst, wenn es dir wieder besser geht. Vielleicht könntest du ein kurzes Beispiel für DllExport zeigen. Wünsche gute Besserung!!! lg, jus |
AW: Wie ein array of record von C# dll mit COM an Delphi übergeben?
Zitat:
Zitat:
Darüber kann man dann noch einen generischen Aufsatz schreiben, damit es einfach zu verwenden ist. Diesen Ansatz habe ich nun schon dreimal entworfen und er wurde jedesmal besser. :-D Zuerst habe ich damit privat gespielt, aber das war nur ein Grundgerüst, dann habe ich es zweimal richtig für berufliche Zwecke implementiert, am Ende dann auch mit C#. |
AW: Wie ein array of record von C# dll mit COM an Delphi übergeben?
Zitat:
Code:
Es funktioniert bei mir irgendwie nicht. Irgendwas mache ich da falsch. Sobald ich den Befehl [DllExport] kommt da folgende Fehlermeldungen:
using System;
using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace DelphiCrossV2 { public class Test { [DllExport] public static int TestExport(int left, int right) { return left + right; } } }
Code:
error CS0246: The type or namespace name 'DllExport' could not be found (are you missing a using directive or an assembly reference?)
error CS0246: The type or namespace name 'DllExport' could not be found (are you missing a using directive or an assembly reference?) |
AW: Wie ein array of record von C# dll mit COM an Delphi übergeben?
Liste der Anhänge anzeigen (Anzahl: 1)
- Klassenbibliothek (.NET Framework) erstellen
- In den Projekteigenschaften unter Build --> Allgemein das Plattformziel auf x86 setzen - Bezeichnungen der Klassen / Namespace usw. setzen - DllExport installieren --> Es öffnet sich dieses Fenster: Anhang 56072 Dort das Häkchen bei "Installed" setzen wie im Screenshot zu sehen und Apply drücken! Der Namespace sollte automatisch passen, wenn es ein neues Projekt ist, aber den kann man dort ggf. auch anpassen. Dann auf Aufforderung des Visual Studios die Mappe neu laden (weil die Projektdatei extern geändert wurde). Nun sollte DllExport gefunden werden. |
AW: Wie ein array of record von C# dll mit COM an Delphi übergeben?
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:44 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