Entwickler-Ecke

Basistechnologien - C# + nativer DLL Export: Aufruf von Supports klappt nicht


jaenicke - Mi 15.06.22 13:50
Titel: C# + nativer DLL Export: Aufruf von Supports klappt nicht
Hallo an alle,

und nun kommt gleich die nächste Frage hinterher.

Gegeben ist folgende (für die Demo stark vereinfachte) Konstellation:
- Visual Studio 2022
- C# Klassenbibliothek mit DllExport via NuGet geladen
- Nativ exportierte DLL-Funktion, die als out Parameter ein IInterface liefert
- Delphi-Programm, das diese DLL lädt und die Funktion ausführt

Nun gibt es offenbar verschiedene Projektformate. Es liegen zwei Projekte mit identischem Quelltext, aber verschiedenen Projektformaten im Archiv. Mit dem einen kann man das zurück gelieferte Interface mit Supports zu einem anderen casten, bei dem anderen klappt es nicht. Beide verwenden das .NET Framework 4.8.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
        [DllExport("DemoFunction", CallingConvention = CallingConvention.StdCall)]
        public static bool DemoFunction(out IntPtr AInterface)
        {
            IDemo demo = new Demo();
            AInterface = Marshal.GetIUnknownForObject(demo);
            return true;
        }



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
procedure TForm2.Button1Click(Sender: TObject);
begin
  TestLibrary('..\..\..\DemoWorking\DemoProject\bin\Debug\DemoProject.dll');
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
  TestLibrary('..\..\..\DemoNotWorking\DemoProject\bin\Debug\DemoProject.dll');
end;

procedure TForm2.TestLibrary(const APath: string);
var
  a: TDemoFunction;
  Intf: IInterface;
  Demo: IDemo;
  Lib: THandle;
begin
  Lib := LoadLibrary(PChar(APath));
  a := GetProcAddress(Lib, 'DemoFunction');
  a(Intf);
  if Supports(Intf, IDemo, Demo) then
    Demo.Run
  else
    ShowMessage('Kann Interface nicht umwandeln!');
end;


Das Delphi-Programm und beide DLLs sind in kompilierter Form vorhanden, d.h. ihr könnt es auch direkt testen.

Wir haben da schon zu zweit gerätselt, haben aber keine Idee. Hat hier einer von euch auch eine Idee?

Danke schon einmal für eure Hilfe!

Viele Grüße
Sebastian


Th69 - Mi 15.06.22 15:25

Hallo again,

du hast aber auch komplizierte Probleme? :lol:

Probiere mal

C#-Quelltext
1:
[assembly: ComVisible(true)]                    

in der "AssemblyInfo.cs" des "DemoNotWorking"-Projekts.


jaenicke - Mi 15.06.22 15:32

ComVisible war mir schon über den Weg gelaufen. Ich hatte das mal an einem Interface direkt stehen. Aber da es in dem einen Projekt auch ohne ging, habe ich es vergessen...

Dass das in einem neuen Projekt dort mit false drin steht, erklärt natürlich alles.

Danke :D