Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Von Delphi Win32 auf .NET Assemblies zugreifen? (https://www.delphipraxis.net/136799-von-delphi-win32-auf-net-assemblies-zugreifen.html)

sh17 8. Jul 2009 07:49


Von Delphi Win32 auf .NET Assemblies zugreifen?
 
Hallo,

also um von Delphi Win32 auf .NET Assemblies zugreifen zu können, gibt es ja mehrere Produkte zur Auswahl. Erste Wahl sind sicher Hydra und CrossTalk.

Gerade der Ansatz von CrossTalk sieht seht intesssant aus.

Meine Frage wäre, wie muss man ansetzen, um so etwas selbst zu implementieren? Kennt jemand OpenSource-Bibliotheken, wo man sich das Prinzip mal anschauen könnte?

VG, Sven

Elvis 8. Jul 2009 08:25

Re: Von Delphi Win32 auf .NET Assemblies zugreifen?
 
Du kannst schon eine ganze Menge über mscoree.dll erreichen.
Damit kannst du Assemblies laden, deren Typen enumerieren und Instanzen anlegen. Das ganze nutzt .Nets ComInterop Technologien, hauptsächlich runtime callable wrappers. (Hydra basiert darauf, CrossTalk und "managed VCL" wahrscheinlich auch)

Es gibt auch die Möglichkeit eine .Net Assembly in eine richtige DLL zu verwandeln.
Oxygene kann in den neuesten Versionen (unter dem "Delphi Prism"-Banner) Funktionen exportieren wie man es von nativen DLLs kennt.
Ich habe mir schon vor einer ganzen Weile einen Satz von Assemblies und dazugehörigem MSBuild-Task gebaut, der es ermöglicht das mit jeder .Net Sprache zu tun.
Man muss statische Methoden nur noch mit DllExport anstatt DllImport markieren und er wird dann die Assembly so anpassen dass diese Methode exportiert wird.

Ich hatte schon ewig vor das mal auf Google Code oder sonstwo zu veröffentlichen, du kannst mir aber eine PN schicken und ich würde dir einfach das geben was ich habe.
Mir ist kein Issue bekannt und ich nutze es in ein paar Projekten als Teil des normalen Builds. (Ist also nicht buggy,bleeding edge *g*)

sh17 8. Jul 2009 08:42

Re: Von Delphi Win32 auf .NET Assemblies zugreifen?
 
Danke, klingt schon mal gut. PN kommt.

Sven

Elvis 8. Jul 2009 17:28

Re: Von Delphi Win32 auf .NET Assemblies zugreifen?
 
Zitat:

Zitat von sh17
Danke, klingt schon mal gut. PN kommt.

Sorry, kam heute nicht mehr dazu.
Ich schicke es dir morgen. Vllt packe ich es dann gleich öffentlich hier hin oder auf Google Code.

Elvis 9. Jul 2009 17:09

Re: Von Delphi Win32 auf .NET Assemblies zugreifen?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Bevor es wieder untergeht.
Hier ist das Archiv mit den Binaries und dem .targets file.

Du musst es einfach nur in deinen Projektordner extrahieren.
  • Um an das Attribut zu kommen, hast du 2 Wege.
    • Der einfachste ist, per "Show all Files" (1) das DllExportAttribute.cs in dein Project zu packen (2)
    • ein anderer ist die RGiesecke.DllExport.DllExportAttribut.dll zu referenzieren.
      Diese Dll ist speziell, denn diese Referenz wird von meinem Build-Task entfernt, genau wie das Attribut von der Methode entfernt wird, wenn er damit fertig ist.
  • Nun musst du dem Projekt nur noch sagen, dass es ein neues Build target gibt.
    • Klicke dafür auf (4) oder Rechtsklick im Solution Explorer\Unload project.
    • Rechtsklick auf das nun graue Project im Solution Explorer -> Edit "Xyz.abc"
    • Jetzt musst du einfach nur noch das hier unterhalb des <Project>-Knotens packen:
      XML-Code:
      <Project ToolsVersion="3.5"
               DefaultTargets="Build"
               xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <Import Project="DllExport\RGiesecke.DllExport.targets" />

Das war's. Er wird dich beim ersten Build warnen, weil du wahrscheinlich als CPU Typ "AnyCPU" stehen hast.
In dem Fall wird er unterhalb des Outputfolders je einen Ordner für x86 und einen für x64 anlegen und dort jeweils die Binaries als x86- und x64 Version ablegen.

Wenn du direkt den CPU Typ in deinem projekt auf x86 oder x64 setzt schreibt er direkt in dein Binary. (Also unter Debug ode Release)

Deine Assemblies sind dann wirkliche DLLs und die exportierten Funktionen verhalten sich eigentlich wie man es auch erwartet. Du kannst sie also als UDF in Firebird nutzen, oder einfach nur als eine bequeme Art .Net Funktionen in Delphi zu nutzen.

Es sollte ab Visual Studio 2005 aufwärts laufen. Oder auch ohne, da es einfach nur .Net 2.0 und MSBuild braucht.
Ich nutze noch ILAsm um die Assembly wieder zusammenzusetzen, dafür braucht man leider das .Net SDK.

Wenn du die Files im Projektordner hast, kann jeder dieses Projekt kompilieren, auf der Maschine muss nichts extra eingestellt werden. (Also zickt auch der Build Server nicht rum ;-) )


Weile es vllt auch andere interessiert habe ich es doch einfach offen reingestellt. ;-)

sh17 10. Jul 2009 05:57

Re: Von Delphi Win32 auf .NET Assemblies zugreifen?
 
Danke Dir. :cheers:

Sven

melv 2. Feb 2010 22:42

Re: Von Delphi Win32 auf .NET Assemblies zugreifen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Elvis,
also ich habe deinen Code in mein Projekt eingebaut. Das mit dem Import des MSBuild Target Skripts hat leider nicht so funktioniert, aber ich habe die Aufrufe einfach direkt in das Projekt Build Skript gepackt. Dann hat er nach dem erstellen des Assemblies als DLL einmal ILDasm aufgerufen und anschließend ILAsm, das hat auch alles super geklappt, aber ich kann die DLL aus Delphi (es ist Delphi 5) nicht einbinden.

Ich versuche Sie statisch einzubinden, so wie du es in deinem Tut. gezeigt hast, aber das Programm stürzt ab mit der Meldung: Die Anwendung konnte nicht richtig initialisiert werden.

Dann hab ich mir die DLL mal mit einem dependecy Viewer angeschaut und ich finde dort gar keine exportierten Funktionsnamen.


Ich kenn mich mit .Net nicht aus, aber ich vermute die erzeugte DLL ist irgendwie nicht ganz i.O.


Ich habe das Ausgabeformat auf x86 gestellt und als .Net Framework benutze ich 3.5

Was funktioniert hat, war der Trick mit den Com Objekten. Allerdings gefällt mir diese Lösung nicht so gut ...


Hast du vielleicht eine Idee dazu?

Der C# Code sieht so aus:
using System.Runtime.InteropServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RGiesecke.DllExport;


namespace HeartsKI
{
public class HeartsKI {
[DllExport("getInt", CallingConvention = CallingConvention.StdCall)]
public static int getInt() {
return 6000;
}
}
}

Beim kompilieren und ausführen deines Build Targets erscheinen folgende Meldungen:
HeartsKI -> C:\Users\jantz\Documents\Visual Studio 2008\Projects\HeartsKI\HeartsKI\bin\Debug\HeartsKI .dll
ILDasm: calling 'C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\ildasm.exe' with /quoteallnames /nobar /linenum "/out:C:\Users\jantz\AppData\Local\Temp\tmpD93A\Hear tsKI.il" "C:\Users\jantz\Documents\Visual Studio 2008\Projects\HeartsKI\HeartsKI\bin\Debug\HeartsKI .dll"
ILAsm: calling 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\ILA sm.exe' with /nologo "/out:C:\Users\jantz\Documents\Visual Studio 2008\Projects\HeartsKI\HeartsKI\bin\Debug\HeartsKI .dll" "C:\Users\jantz\AppData\Local\Temp\tmpD93A\HeartsK I.il" /DLL "/resource=C:\Users\jantz\AppData\Local\Temp\tmpD93A \HeartsKI.res" /debug

im Delphi Code ist das ganze dann so deklariert:


function getInt():Integer; stdcall; external 'HeartsKI.dll';

Ich habe die compilierte DLL mal angehangen.

Elvis 6. Mär 2011 22:01

AW: Re: Von Delphi Win32 auf .NET Assemblies zugreifen?
 
Zitat:

Zitat von melv (Beitrag 994969)
Hi Elvis,
also ich habe deinen Code in mein Projekt eingebaut. Das mit dem Import des MSBuild Target Skripts hat leider nicht so funktioniert

Habe deinen Beitrag eben erst gesehen.
Für den unwahrscheinlichen Fall, dass es noch relevant für dich ist, oder falls andere hier auf das gleiche Thema stoßen:
Ich hatte schon vor längerem das ganze auf eine kleine Google Site gepackt und weiß von vielen Leuten, die die dortige Version erfolgreich und problemlos für alles mögliche einsetzen.


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