Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   C# DLL in Delphi nutzen (https://www.delphipraxis.net/210271-c-dll-delphi-nutzen.html)

sonny2007 27. Mär 2022 20:15

C# DLL in Delphi nutzen
 
Hallo Zusammen

(Delphi 10.4)

Ich möchte gerne eine function aus einer C# DLL in delphi aufrufen und verwenden.
Die C# Dll sieht so aus

Code:
using MessagePack;
using RGiesecke.DllExport;
using System;
using System.Runtime.InteropServices;

namespace MsgPack.Native
{
   public class Exports
   {
      [DllExport(CallingConvention = CallingConvention.StdCall)]
      [return: MarshalAs(UnmanagedType.BStr)]
      public static string ConvertToJson(IntPtr pBytes, int cBytes)
      {
         byte[] data = new byte[cBytes];
         Marshal.Copy(pBytes, data, 0, cBytes);
         string result = MessagePackSerializer.ConvertToJson(data);
         return result;
      }
   }
}

Die definition in Delphi sieht aktuell so aus.
Delphi-Quellcode:
type
  TConvertToJson = function(pBytes: Pbyte; cBytes: Integer): string; stdcall;
Der Aufruf
Delphi-Quellcode:
dllhandle := loadlibrary('MsgPack.Native.dll') ;
  if dllhandle <> 0 then
    @ConverToJson := GetProcAddress(dllhandle, 'ConvertToJson');
    if @ConverToJson <> nil then  // <<--------------- Ist immer NIL
    begin
und so würde der Aufruf selber aussehen.
Delphi-Quellcode:
tmp := ConverToJson(@buf[0], length(Buf));
Jedoch gib GetProcAdress gibt immer NIL aus
Was mache ich falsch?

Grüße
s0n

Der schöne Günther 27. Mär 2022 20:20

AW: C# DLL in Delphi nutzen
 
Delphi-Quellcode:
LoadLibrary(..)
aber funktioniert?

sonny2007 27. Mär 2022 20:25

AW: C# DLL in Delphi nutzen
 
Ja LoadLibrary geht

TSchnuckenbock 27. Mär 2022 20:26

AW: C# DLL in Delphi nutzen
 
Mein nächster Ansatz wäre: Mit dem DependencyWalker in die dll gucken, ob unter "ConvertToJson" auch was drin steht?

Der schöne Günther 27. Mär 2022 20:33

AW: C# DLL in Delphi nutzen
 
Oh, verrückt. Ich hätte erwartet dass man das in .NET noch auf "AnyCPU" oder so hatte (statt x86 oder x64) - Aber wenn LoadLibrary(..) an sich funktioniert dann scheint es daran ja wohl nicht zu liegen...

arnold mueller 27. Mär 2022 21:08

AW: C# DLL in Delphi nutzen
 
könntest du die DLL mal hier zur Verfügung stellen?

Aviator 27. Mär 2022 21:21

AW: C# DLL in Delphi nutzen
 
Ich wollte damals auch mal eine in C# geschriebene DLL in Delphi nutzen. Dafür musste dann die DLL aber mit einem speziellen Unmanaged Exports Helper kompiliert werden. Ansonsten sind die nicht wirklich sichtbar. Ob sich daran etwas geändert hat (vor allem auch mit den Attributen die ja gesetzt sind) weiß ich nicht. Glücklicherweise hatte ich die DLL damals selbst geschrieben und konnte das dann auch selbst alles machen.

Aber dem Tipp mit dem Dependency Walker solltest du definitiv folgen um zu sehen ob überhaupt etwas exportiert wird.

venice2 27. Mär 2022 21:35

AW: C# DLL in Delphi nutzen
 
Hmmm...
Code:
function ConvertToJson(pBytes: Pbyte; cBytes: Integer): string; stdcall; external 'MsgPack.Native.dll';

Aviator 27. Mär 2022 21:37

AW: C# DLL in Delphi nutzen
 
Bringt nur nix wenn die Methode gar nicht exportiert wird und unterscheidet sich auch nicht wirklich von seiner Version. Oder übersehe ich etwas?

venice2 27. Mär 2022 21:40

AW: C# DLL in Delphi nutzen
 
Zitat:

Zitat von Aviator (Beitrag 1504002)
Bringt nur nix wenn die Methode gar nicht exportiert wird und unterscheidet sich auch nicht wirklich von seiner Version. Oder übersehe ich etwas?

Jo warum dann LoadLibrary (gar nicht nötig) wenn sich die DLL im Anwendungspfad befindet.
Entweder es kommt was zurück beim direkten Aufruf oder nicht.

Und sie wird exportiert!
Code:
[DllExport(CallingConvention = CallingConvention.StdCall)]

Aviator 27. Mär 2022 21:48

AW: C# DLL in Delphi nutzen
 
Delphi-Quellcode:
LoadLibrary()
hat den Vorteil des Lazy Loadings. Wenn die DLL also nicht beim Programmstart direkt zur Verfügung stehe muss, dann kann man die auch erst verzögert laden. Macht den Anwendungsstart ggf. auch etwas schneller.

Und nur weil das Attribut darüber steht heißt das bei C# nicht zwangsläufig, dass die Methode auch exportiert wird. Zumindest ist das meine Erfahrung.

venice2 27. Mär 2022 21:55

AW: C# DLL in Delphi nutzen
 
Zitat:

Und nur weil das Attribut darüber steht heißt das bei C# nicht zwangsläufig, dass die Methode auch exportiert wird. Zumindest ist das meine Erfahrung.
Schlechte Erfahrungen gemacht? Na gut denn.
Meine Erfahrung entspricht deinem Gegenteil. aber muß mich nicht streiten.

hoika 28. Mär 2022 06:09

AW: C# DLL in Delphi nutzen
 
Hallo,
unter c++ wird an den Methodennamen immer was drangehangen,
vielleicht ist es in c# ja auch so.

Fritzew 28. Mär 2022 07:48

AW: C# DLL in Delphi nutzen
 
Du musst die Zielplattform im c# Projekt auf x86 setzten.

Die Declaration von

Delphi-Quellcode:
function ConvertToJson(pBytes: Pbyte; cBytes: Integer): string; stdcall; external 'MsgPack.Native.dll';
mit Rückgabe String wird auch nicht funktionieren.

Versuche es mit PWChar

sh17 28. Mär 2022 09:25

AW: C# DLL in Delphi nutzen
 
Müsste es nicht

ConverToJson := GetProcAddress(dllhandle, 'ConvertToJson');

heißen?

Und evtl WideString anstatt String in der Deklaration der Funktion. Das mit 32bit und 64bit ist immer
etwas schwierig einzustellen in VS finde ich.

Nutzt Du DLLExport 1.7.4.? Al Beispiel mal mein Projekt

https://github.com/landrix/LibPhonenumber-for-Delphi

venice2 28. Mär 2022 11:40

AW: C# DLL in Delphi nutzen
 
Zitat:

Das mit 32bit und 64bit ist immer
etwas schwierig einzustellen in VS finde ich.
Ist doch gut gelöst Debug\Release "COMBO" und dort Konfigurations-Manager starten.

bzgl. x86 und x64 ist so ein Problem.
Was bringt es wenn die Bibliothek RGiesecke.DllExport mit AnyCPU kompiliert wurde das beißt sich doch irgendwie.

Delphi DLL -> C# über DllImport ist kein Problem.
C# DLL über DllExport hingegen schon. (Leider)

bsp.
Code:
namespace CalcTest
{
    using System.Runtime.InteropServices;
    using RGiesecke.DllExport;

    public sealed class CalcTest
    {
        [DllExport(CallingConvention = CallingConvention.StdCall)]
        public static int Sum(int a, int b)
        {
            return a + b;
        }
    }

}
Delphi.
Delphi-Quellcode:
function Sum(a, b: integer): integer; stdcall; external 'Calctest.Net.dll';


Delphi Anwendung stürzt sofort ab.. läßt sich nicht starten!

Fehler!
Der Fehler 0xc000007b tritt typischerweise auf, wenn die 32-Bit-Version von Windows mit einem 64-Bit-Betriebssystem oder -Anwendungen verwechselt wurde.
Projekt ist aber x86 C# DLL ebenso jedoch RGiesecke.DllExport AnyCPU ..

EDIT:
RGiesecke.DllExport neu kompiliert 32Bit\x86 alle Frameworks 4.8 trotzdem selber Fehler.

sh17 28. Mär 2022 12:01

AW: C# DLL in Delphi nutzen
 
Also mit der Lib von Robert Giesecke war irgend wann Ende im Gelände. Bin dann zu DLLExport gewechselt, was grob auf RGiesecke basiert, aber eine Neuentwicklung ist.

venice2 28. Mär 2022 12:12

AW: C# DLL in Delphi nutzen
 
Zitat:

Zitat von sh17 (Beitrag 1504041)
Also mit der Lib von Robert Giesecke war irgend wann Ende im Gelände. Bin dann zu DLLExport gewechselt, was grob auf RGiesecke basiert, aber eine Neuentwicklung ist.

Ahh.. kann natürlich sein.

venice2 28. Mär 2022 13:20

AW: C# DLL in Delphi nutzen
 
Damit funktioniert es nun.
Offline Package von DLLExport im Archiv.

genug damit gespielt.

Wenn er nun das als Beispiel nimmt und sein Projekt entsprechend anpaßt wird es wohl funktionieren.
DLLExport ist nötig.. Die neue (siehe Package) ohne geht es nicht!
Danke an @sh17 für die Info.

Werde die Anhänge später wieder löschen.

Aviator 28. Mär 2022 21:59

AW: C# DLL in Delphi nutzen
 
Zitat:

Zitat von venice2 (Beitrag 1504044)
DLLExport ist nötig.. Die neue (siehe Package) ohne geht es nicht!

Was ich gestern die ganze Zeit gesagt habe. Aber du denkst ja immer direkt das jeder mit dir streiten will ... :roll:

venice2 29. Mär 2022 10:31

AW: C# DLL in Delphi nutzen
 
Zitat:

Zitat von Aviator (Beitrag 1504057)
Zitat:

Zitat von venice2 (Beitrag 1504044)
DLLExport ist nötig.. Die neue (siehe Package) ohne geht es nicht!

Was ich gestern die ganze Zeit gesagt habe.

Kein LoadLibrary..
Zitat:

Aber du denkst ja immer direkt das jeder mit dir streiten will ... :roll:
Meine Jahre lange Erfahrung hier. Wäre oder ist nicht das erste mal.

Habe nur gute Erfahrung unter C# -> Delphi gemacht und umgekehrt weil alles soweit selbst geschrieben siehe meinen C# Wrapper für .NET für Bass_vis(Delphi DLL).
Du hattest halt schlechte Erfahrung und deshalb will ich nicht mit dir streiten.. Schrieb ich schon.

Problem gelöst Anhang gelöscht.

MTranel 29. Mär 2022 11:25

AW: C# DLL in Delphi nutzen
 
Ich mach hier mal ganz kurz Werbung für mein NuGet Package was genau für diesen UseCase gebaut wurde.
Es arbeitet im Grunde genau wie UnmanagedExports nur das die Internals auf DNLib anstatt auf ildasm/ilasm basieren. Dadurch spart ihr euch das ab und zu die DLL baut aber keine Exports drin landen, weil euch irgendwelche Windows 10 SDKs fehlen. Und DLLExport ist zwar nett, aber mir passt das extra GUI zum exportieren im Nachhinein gar nicht.

https://github.com/MeikTranel/NXPorts

In den Samples ist das alles ganz gut dargestellt. Die Schnittstelle der Attribute ist quasi deckungsgleich mit der von RGiesecke und der Rest passiert automatisch.

sh17 29. Mär 2022 15:02

AW: C# DLL in Delphi nutzen
 
Zitat:

Zitat von MTranel (Beitrag 1504080)
Ich mach hier mal ganz kurz Werbung für mein NuGet Package was genau für diesen UseCase gebaut wurde.
Es arbeitet im Grunde genau wie UnmanagedExports nur das die Internals auf DNLib anstatt auf ildasm/ilasm basieren. Dadurch spart ihr euch das ab und zu die DLL baut aber keine Exports drin landen, weil euch irgendwelche Windows 10 SDKs fehlen. Und DLLExport ist zwar nett, aber mir passt das extra GUI zum exportieren im Nachhinein gar nicht.

https://github.com/MeikTranel/NXPorts

In den Samples ist das alles ganz gut dargestellt. Die Schnittstelle der Attribute ist quasi deckungsgleich mit der von RGiesecke und der Rest passiert automatisch.

Cool, kannte ich noch nicht, gleich mal markiert.

generic 29. Mär 2022 22:50

AW: C# DLL in Delphi nutzen
 
Du kannst in C# einen COM Server erstellen. Dessen interface exportierst du und importierst die TLB dann in Delphi.
Damit du den COM-Server nicht Registieren brauchst, nutzt du einfach Side-by-Side Konfiguration.

Das erspart viel fehleranfällige Schnittstellendefinitionen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:21 Uhr.

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