Autor Beitrag
xuxu81
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Sa 28.04.18 15:49 
Hallo zusammen,

für mein Projekt wird eine DLL benötigt. Derzeit liegt sie im selben Ordner wie die Anwendung, es soll aber auch die Möglichkeit geboten werden, sie auszulagern (z.B. in einem Unterordner). Mir ist der genaue Pfad also erst zur Laufzeit bekannt, leider erfordert DllImport aber einen konstanten Wert (String).

Weiß zufällig jemand eine elegante Möglichkeit, das ganze dynamisch einzubinden? Oder eine Alternative zu DllImport (bestenfalls mit einem Link zu einem Beispiel was ihr als Praxistest empfehlen könnt)?

Vorab schon mal vielen lieben Dank für eure Zeit und Mühe. :)
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 28.04.18 17:27 
Entweder du ergänzt den Suchpfad für Dlls via SetDllDirectory so das DllImport auch dieses Verzeichnis durchsucht wenn es versucht die Dll zu laden oder du lädst die entsprechende Dll vorab per LoadLibrary. DllImport benutzt die dann einfach wenn die schon im Speicher ist.

Für diesen Beitrag haben gedankt: xuxu81
xuxu81 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Sa 28.04.18 17:44 
Danke, hilfreicher Tipp! :)

Funktioniert aber nicht, wenn der Name der Bibliothek auch dynamisch ist, oder? Könnte möglicherweise etwas klappen, dass er einfach alle Bibliotheken innerhalb eines Verzeichnis importiert und ich dann direkt auf die Methoden darin zugreifen kann?

Im Grunde sowas wie
ausblenden C#-Quelltext
1:
foreach (string dll in Directory.GetFiles(path, "*.dll")) Assembly.LoadFile(dll);					

was aber nur für die Wrapper Klasse funktionieren würde, nicht für die eigentlichen Bibliotheken (unmanaged).

Moderiert von user profile iconTh69: Code- durch C#-Tags ersetzt
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 28.04.18 18:28 
Wenn bei dir alles dynamisch ist bleibt dann nur dynamischer Code und DllImport ist raus. Um noch halbwegs vernünftig zur Designzeit damit arbeiten zu können hilft Marshal.GetDelegateForFunctionPointer

Aber am besten erzählst du erstmal warum du willst was du da willst. Ich erkenne da gerade keinen sinnvollen Anwendungsfall. Ganz zu schwiegen von den Bauchschmerzen die es mir bereitet einfach mal alles was in einem Verzeichnis liegt in den Prozessraum zu laden.
xuxu81 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Sa 28.04.18 19:00 
Also, im Grunde hatte ich für mein Projekt eine DLL und nach einiger Suche auch eine entsprechende Wrapper Klasse gefunden. Die Funktionalität war für meine Wünsche aber noch nicht vollständig, also habe ich beide entsprechend erweitert und möchte diese in naher Zukunft bei Github veröffentlichen.

Allerdings hat es mich schon immer gestört, wenn der Nutzer dann mit den statischen Dateinamen/Pfaden leben, oder entsprechend neu kompilieren muss, anstatt diese einfach nach seinen persönlichen Wünschen in sein Projekt einbinden zu können.

Vereinfacht ausgedrückt habe ich in der Wrapper Klasse derzeit
ausblenden C#-Quelltext
1:
2:
3:
const String _dllimp="blabla.dll";
[DllImport(_dllimp, EntryPoint = "blabla_one", CallingConvention = CallingConvention.Cdecl)]
...

und hätte gerne
ausblenden C#-Quelltext
1:
2:
3:
String _dllimp=GetFileAndPath();
[DllImport(_dllimp, EntryPoint = "blabla_one", CallingConvention = CallingConvention.Cdecl)]
...


Moderiert von user profile iconTh69: Code- durch C#-Tags ersetzt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 29.04.18 12:01 
Ich selber habe noch nicht damit gearbeitet, aber du könntest das AppDomain.AssemblyResolve-Ereignis dazu benutzen (d.h. du checkst dadrin auf den vorher fest zugewiesenen DllImport-Namen und lädst dann dynamisch die Assembly).
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 29.04.18 12:49 
- Nachträglich durch die Entwickler-Ecke gelöscht -


Zuletzt bearbeitet von Frühlingsrolle am Mo 30.04.18 05:05, insgesamt 1-mal bearbeitet

Für diesen Beitrag haben gedankt: xuxu81
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 29.04.18 13:00 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Ich selber habe noch nicht damit gearbeitet, aber du könntest das AppDomain.AssemblyResolve-Ereignis dazu benutzen (d.h. du checkst dadrin auf den vorher fest zugewiesenen DllImport-Namen und lädst dann dynamisch die Assembly).

Das funktioniert auch für unmanaged Dlls und nicht nur für Assemblies?

user profile iconxuxu81 hat folgendes geschrieben Zum zitierten Posting springen:
Allerdings hat es mich schon immer gestört, wenn der Nutzer dann mit den statischen Dateinamen/Pfaden leben, oder entsprechend neu kompilieren muss, anstatt diese einfach nach seinen persönlichen Wünschen in sein Projekt einbinden zu können.


Ein weiterer simple Lösung wäre die irgendwo liegende Dll mit irgendeinem Namen einfach durch Code an eine Stelle zu kopieren und passend zu benennen von wo sie dann durch DLLImport geladen wird. Der kopierende Code kann dann irgendeine Konfiguration/Variablen benutzen die mit dem tatsächlichen Namen bzw. tatsächlichen Lagerort umgehen können.

Für diesen Beitrag haben gedankt: xuxu81
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 29.04.18 14:14 
Ups, da war ich wohl noch nicht ganz wach. ;-) Du hast recht, das geht nur für managed DLLs (Assemblies) - also vergesst den Vorschlag.
xuxu81 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 29.04.18 15:18 
Hallo zusammen und vielen Dank für eure Antworten.

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Ich verwende sowas in Delphi. Das hier ist "mein erstes Mal" in C#. :D

Danke Dir! :) Hatte den Weg auch schon mehrfach bei meiner Googlesuche gesehen und werde es wohl auch auf die Art machen, wenn ich keine bessere Methode finde. ^^

user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Ein weiterer simple Lösung wäre die irgendwo liegende Dll mit irgendeinem Namen einfach durch Code an eine Stelle zu kopieren und passend zu benennen von wo sie dann durch DLLImport geladen wird. Der kopierende Code kann dann irgendeine Konfiguration/Variablen benutzen die mit dem tatsächlichen Namen bzw. tatsächlichen Lagerort umgehen können.

Ich bin nicht sicher, ob ich Dich richtig verstanden habe: Meinst Du die Pfade/Namen im Code statisch zu belassen, dann vor dem Importieren in die eigentliche Anwendung die Bibliotheken zu suchen, an die statisch vorgesehenen Orte zu kopieren und dann mit diesen zu arbeiten und ggf. beim Schließen der App die temporären Kopien wieder zu löschen..?

Könnte ein funktionierendes Workaround sein.