Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Parameter Count aus einer DLL Methode
Nejox
myCSharp.de - Member



Dabei seit:
Beiträge: 19

Themenstarter:

Parameter Count aus einer DLL Methode

beantworten | zitieren | melden

Hallo zusammen,

ich bin mir gerade nich sicher wonach ich Suchen soll. Ich wollte mal in Erfahrung bringen ob es möglich ist die Anzahl von Parametern aus einer DLL Methode zu bekommen?

Ich habe folgenden Code


public class MyClass
{
        [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        private static extern IntPtr LoadLibrary(string library);

        [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string methodName);

        public void LoadDll()
       {
           IntPtr module = LoadLibrary("myDll");

           // Fehler behandlung wenn DLL nicht gefunden wurde
            if (module == IntPtr.Zero)
            {
                return $"Could not load library: {Marshal.GetLastWin32Error()}";
            }

            IntPtr dllMethod = GetProcAddress(module, "myFunction");

            // Fehler behandlung wenn Methode in der DLL nicht gefunden wurde
            if (dllMethod== IntPtr.Zero)
            {
                return $"Fehler beim Laden der DLL Methode { Marshal.GetLastWin32Error() }";
            }

             // Hier möchte ich nun abfragen wieviel Parameter in der dll Methode "myFunction" vorhanden sind.
        }
}

Freue mich auf eine Antwort :-)
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4140

beantworten | zitieren | melden

Das ist technisch nicht möglich. Die Parameter von nativen (z.B. in C oder C++ geschriebenen) Funktionen werden über den Stack (welches einfach nur ein Byte-Array darstellt) übergeben und ausgelesen. Genausowenig ist es daher möglich die genauen Datentypen der Parameter abzufragen, ohne den Code zu kennen. Daher ist es zur Verwendung zwingend nötig, die genaue Signatur der Funktion zu kennen.

Anders sieht es bei .NET aus, da diese mittels Reflection erfragt werden können.
private Nachricht | Beiträge des Benutzers
ClaraSoft
myCSharp.de - Member



Dabei seit:
Beiträge: 36

beantworten | zitieren | melden

Wenn du wirklich ein Plugin System bastelen möchtest, dann solltest du dir noch mal Gedanken über dein Konzept machen. So wie das aktuell ist, kann es nur nach hinten losgehen.

Dein Plugin sollte eine Schnittstelle haben, die das Programm, welches das Plugin nutzen möchte eindeutig versteht. Das kann man Besten über ein Interface machen, das dein Plugin implementiert und dein Programm laden kann. Dann musst auch nicht mehr die Parameter herausfinden, da alles mit einer eindeutigen Schnittstelle bekannt sein sollte für beide Seiten.

Hier noch etwas ausführlicher:
Erstellen einer .NET Core-Anwendung mit Plug-Ins - .NET
private Nachricht | Beiträge des Benutzers
Nejox
myCSharp.de - Member



Dabei seit:
Beiträge: 19

Themenstarter:

beantworten | zitieren | melden

Danke für die Antworten.

@ClaraSoft
Hättest du hier mal ein Beispielprogramm? Kann mir das ehrlich gesagt noch nicht so richtig vorstellen.
private Nachricht | Beiträge des Benutzers
ClaraSoft
myCSharp.de - Member



Dabei seit:
Beiträge: 36

beantworten | zitieren | melden

Steht alles im Link beschrieben, den ich gepostet habe.
private Nachricht | Beiträge des Benutzers
Nejox
myCSharp.de - Member



Dabei seit:
Beiträge: 19

Themenstarter:

beantworten | zitieren | melden

Ah sorry habs gerade geshen
Danke.
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4140

beantworten | zitieren | melden

Das funktioniert aber nur für .NET-Assemblies, nicht für native DLLs.

Oder ist "myDll" gar keine native DLL und du hast nur die falsche Methode zum Laden benutzt?
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2136

beantworten | zitieren | melden

Mal angemerkt, selbst wenn man rausfinden könnte *wie viele* Parameter eine Methode/Funktion hat, weiß man ja immer noch nicht *welche* das sind.
Würde also nicht sehr viel bringen, denn man hat dann immer noch keinen Hinweis darauf was man da nun übergeben soll.
private Nachricht | Beiträge des Benutzers
Nejox
myCSharp.de - Member



Dabei seit:
Beiträge: 19

Themenstarter:

beantworten | zitieren | melden

MyDll ist eine Fremd Dll auf C bzw. C++ Basis soweit ich weiß.
private Nachricht | Beiträge des Benutzers
Nejox
myCSharp.de - Member



Dabei seit:
Beiträge: 19

Themenstarter:

beantworten | zitieren | melden

Zitat von ClaraSoft
Wenn du wirklich ein Plugin System bastelen möchtest, dann solltest du dir noch mal Gedanken über dein Konzept machen. So wie das aktuell ist, kann es nur nach hinten losgehen.

Dein Plugin sollte eine Schnittstelle haben, die das Programm, welches das Plugin nutzen möchte eindeutig versteht. Das kann man Besten über ein Interface machen, das dein Plugin implementiert und dein Programm laden kann. Dann musst auch nicht mehr die Parameter herausfinden, da alles mit einer eindeutigen Schnittstelle bekannt sein sollte für beide Seiten.

Hier noch etwas ausführlicher:
Erstellen einer .NET Core-Anwendung mit Plug-Ins - .NET


Ich wollte nochmal nachfragen ob du davon ausgegangen bist das "myDll" eine dll von mir ist?
Wenn ja, ist sie nicht. Sorry für das Missverständniss. Hätte es dann anders benennen sollen. Ich muss damit arbeiten und kann auch nichts an der "myDll" ändern.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Nejox am .
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4140

beantworten | zitieren | melden

Zitat von Nejox
MyDll ist eine Fremd Dll auf C bzw. C++ Basis soweit ich weiß.
Dann sollte es dafür doch eine zugehörige Headerdatei (.h oder .hpp) geben, in der die Funktionen deklariert sind. Die Aufrufe mußt du dann nur per "Marshalling" nach C# übertragen (also so wie du es bisher auch für die Funktionen LoadLibrary und GetProcAddress per DllImport gemacht hast) - du mußt die DLL also nicht dynamisch laden (außer du willst wirklich ein Plugin-System realisieren, d.h. beliebig benannte DLLs mit einheitlicher Schnittstelle aufrufen zu können).

s.a. Verwenden nicht verwalteter DLL-Funktionen
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am .
private Nachricht | Beiträge des Benutzers
Nejox
myCSharp.de - Member



Dabei seit:
Beiträge: 19

Themenstarter:

beantworten | zitieren | melden

Ich möchte das ganze eher Dynamisch händeln. Der Grund ist das es mehrere Versionen von der aufzurufenden DLL gibt. Hier muss ich bestimmte Unterscheidungen machen was für eine Version genutzt werden soll. Sonst müsste ich ja jede einzelne DLL als DLL Import definieren. Oder sehe ich das falsch?


Moderationshinweis von Abt (07.06.2021 - 14:38:57):

Bitte keine Full Quotes.

private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Member

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1512
Herkunft: Düsseldorf

beantworten | zitieren | melden

Das geht nicht dynamisch, irgendwo brauchst Du einen gemeinsamen Stand, anhand dessen Du weißt, wie Du XY aufrufen kannst.
Hast Du diesen gemeinsamen Stand nicht, musst Du wohl oder übel alles einzeln machen.
Oder Du rätst, was es für Parameter gibt, wirst dann aber ziemlich sicher irgendwann den Fall haben, dass Du die richtigen Parameter nicht errätst.

Deshalb sollte man das auch umdrehen:
Nicht dein Programm muss die externe DLL und die Parameter der Methoden kennen, sondern die externe DLL kennt dein Programm.
Dein Programm liefert dafür dann eine Schnittstelle, die die externe DLL nutzt - das ist dein gemeinsamer Stand.

Du könntest also ein Interface definieren, wo die Methode, die Du brauchst, definiert ist und als Parameter wird alles übergeben, was Du bieten kannst/darfst.
Die externe DLL muss dann dieses Interface implementieren und kann dann die Daten so weiter reichen, wie es für die jeweilige Version richtig ist.
Diese Implementierung findest Du dann via Reflection oder einer Art Registrierungs-Interface, was aber auch wieder implementiert und irgendwie gefunden werden muss.
Dein Programm bekommt dann die Implementierung und hat ein eindeutiges Interface zum Aufrufen.

Bei externen DLLs geht das natürlich nicht so einfach, da brauchst Du denn einen Vermittler dazwischen - je Version.
Dieser Vermittler implementiert dein Interface und ruft darin die externe Version auf, der muss dann immer angepasst werden, dein Haupt-Programm bleibt dabei aber unberührt.
Der Vermittler kann in C# oder C++/CLI geschrieben werden, je nachdem, was einfacher ist, hauptsache es kommt eine managed DLL bei raus.
Du kannst natürlich auch unmanaged arbeiten, kannst dann aber nicht mit .NET-Interfaces arbeiten und musst irgendwie anders die native Methode definieren, die dein Programm aufruft.

Der Nachteil ist, dass Du je Version eine zusätzliche DLL brauchst, aber je nach Umfang der externen Methoden ist das nur sehr wenig Arbeit.
Außerdem sehe ich das nicht als Nachteil, sondern als Vorteil, denn Du hast einen einzigen Punkt, den Du anpassen musst und gefährdest dein restliches Programm nicht.
Die könnte man z.B. sogar zur Laufzeit austauschen oder als einzige DLL raus geben, ohne das ganze Programm aktualisieren zu müssen.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Palladin007 am .
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4140

beantworten | zitieren | melden

Verstehe ich das richtig, daß du daher aufgrund deiner Frage zur Parameteranzahl damit herausfinden möchtest, um welche Version es sich handelt?
Das ist, wie schon geschrieben, so nicht möglich.

Und beim Aufrufen der Funktionen per dynamischen Laden müßtest du ja sowieso Marshal.GetDelegateForFunctionPointer (LOL: "marshal" wird als "Mars Hallen" übersetzt) benutzen und dafür dann je nach Funktionsvariante passende Delegates erzeugen.

Du solltest einfach alle Funktionsvarianten (welche du in deinem Programm auch aufrufen möchtest) per DllImport erzeugen (ich nehme an, die DLL hat immer denselben Namen). Du mußt dann nur in deinem Programm eine passende Logik einbauen, welche die verschiedenen Versionen erkennt (evtl. die Datei-Info auslesen?) und dementsprechend dessen Funktionsvarianten aufruft.

Warum gibt es überhaupt verschiedene Versionen der DLLs, die dein Programm unterstützen soll?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16112

beantworten | zitieren | melden

Zitat von Nejox
Sonst müsste ich ja jede einzelne DLL als DLL Import definieren. Oder sehe ich das falsch?
Mir ist auch immer noch völlig unklar, was Du tun willst; was Du mit dynamisch meinst.

Soll Deine Anwendung einfach prinzipiell verschiedene Versionen einer Abhängigkeit unterstützen, oder sollen diese auch noch dynamisch während der Laufzeit ausgetauscht werden?
Beides ist prinzipiell (mit unterschiedlichem Aufwand) umsetzbar; aber in allen Fällen würde man das nicht versuchen mit schwarzer Magie sondern mit strukturierten Vorgehen lösen wollen.

Fixe Version während der Runtime: kann man über eine klassische 0815 Pluginstruktur lösen.
Austausch während der Runtime: in .NET Core 3+ / .NET 5 gar nicht so einfach zu lösen, da es keine App Domains mehr gibt; der AssemblyLoadContext bietet aber grundlegende Funktionen dafür an.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers