Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   .NET-Framework (managed code) (https://www.delphipraxis.net/79-net-framework-managed-code/)
-   -   Einbindung von externen DLLs in Delphi (https://www.delphipraxis.net/193180-einbindung-von-externen-dlls-delphi.html)

Rabenrecht 30. Jun 2017 12:57

Einbindung von externen DLLs in Delphi
 
Edit: bin mir nicht sicher, ob das Thema im passenden Unterforum ist. Wenn nicht, gerne dahin verschieben, wo es besser passt

Das ist absolutes Neuland für mich und nach meiner bisherigen Recherche kann man dabei jede Menge falsch machen.

Daher frage ich lieber bei euch Experten hier nach :P


Der Sachverhalt: Ich möchte in Delphi eine Funktion einer von mir in C#* geschriebenen Klassenbibliothek aufrufen.

Auf C# Seite sieht das folgendermaßen aus:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RGiesecke.DllExport;
using System.DirectoryServices;
using System.Runtime.InteropServices;

namespace MyClassLib
{
    public class Class1
    {
        [DllExport("MyCoolFunc", CallingConvention = CallingConvention.StdCall)]
        [return: MarshalAs(UnmanagedType.BStr)]
        public static string MyCoolFunc(String path, String filter, String[] attributes, String[] fieldNames, int depth)
        {
            //STUFF
           ...
           Return = "cool";
        }
    }
}
Zum Exportieren verwende ich das NuGet-Paket UnmanagedExports von Robert Gieseke.

Die Frage ist nun, wie man die Sachen in Delphi einbindet. Nachdem, was ich bisher gelesen habe, müsste das folgendermaßen aussehen:

Delphi-Quellcode:
type
  TCoolClass = class
  private
    function CoolFunction(path, filter: String; attributes, fieldNames: Array of String; depth: integer):WideString; stdcall;
  public
    function TestIfCool:Boolean;
  end;

implementation

function TCoolClass.CoolFunction; external "MyClassLib.dll";

function TCoolClass.TestIfCool:Boolean;
var
  vPath,
  vFilter      : String;
  vAttributes,
  vFieldNames  : Array of String;
  vDepth       : Integer;
begin
  vPath := 'DC=foo,DC=bar';
  vFiler := '(&(Name=foobar))';
  SetLength(vAttributes,2);
  vAttributes[0] := 'foo';
  vAttributes[1] := 'bar';
  SetLength(vFieldNames,2);
  vFieldNames[0] := 'FOO';
  vFieldNames[1] := 'BAR';
  vDepth := 2;

  if CoolFunction(vPath,vFilter,vAttributes,vFieldNames,vDepth) = 'cool' then
    return := true
  else
    return := false;
end;
Aber so einfach wird es denke ich nicht sein. Die Frage, die sich mir am stärksten aufdrängt, ist die nach der Kompatibilität der Typen: CoolFunc hat als Parameter String, Integer und String Arrays. In C# gibt es natürlich Entsprechungen, aber jeder Programmiersprache implementiert diese Typen ja auf eigene Weise. Da könnte es schon zu Problemen kommen.

Welche Typen sollte ich bei externen Aufrufen also nach Möglichkeit nur verwenden? Sind Datenstrukturen wie Arrays bei sowas überhaupt möglich?

Das ganze Thema ist wie gesagt komplett neu für mich, daher freue ich mich über jeden Input :-)

*dass ich C# für die Implementierung verwendet habe, dürfte hier ziemlich unerheblich sein, da sich meine Fragen für zb. VB oder c++ genauso stellen würden

TiGü 30. Jun 2017 14:07

AW: Einbindung von externen DLLs in Delphi
 
Du sagst beim Rückgabewert ja schon, dass es ein BStr sein soll, das müsste auch für die Eingangsargumente gelten ([return: MarshalAs(UnmanagedType.BStr)]).
Auf Delphi-Seite dann den Typ WideString anstatt String nehmen.

Rabenrecht 4. Jul 2017 15:04

AW: Einbindung von externen DLLs in Delphi
 
Hat geklappt :)

Zusätzlich zum Marshallen der Parameter musste ich allerdings anstatt eine Rückgabewert zu verwenden einen "out" Parameter nutzen.

Bei Rückgabetypen, die man nicht marschallen braucht (wie Int), ging es auch so, aber Strings wurden immer "verschluckt".


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