C# Dll einbinden

Zera Kakkade

Grünschnabel
Hi an alle :)

Nach dem schönen Weihnachtsfest, komme ich direkt mal mit einer kleinen frage.

Ich habe zwar schon einige Themen dazu gefunden doch führte keines dieser Themen dazu, das mein Testprogramm läuft.

Ich habe vor, ein Programm zu schreiben, das stehts durch kleine Module erweiterbar ist. Daher begann ich ein Programm zu schreiben, welches zu beginn alle DLL- Datein aus einem Ordner lädt und ihre Startfunktion ausführt. Die Startfunktion soll später bei jeder DLL- Datei die selbe sein.

Sowohl das Hauptprogramm als auch die DLL- Datein sind mit c# entwickelt und das solte auch so bleiben.

Nun habe ich folgende Test Methode geschrieben um die DLL zu laden:
Code:
        [DllImport("mod\\mod_mod.dll")]
        extern public static void ShowTest();

        //wird ausgeführt wenn Hauptmaske geladen ist
        private void LoadStartOptions(object sender, EventArgs e)
        {
                ShowTest();
        }

Die DLL- Datei ist wie folgt aufgebaut:
Code:
namespace mod_mod
{
    public class Class1
    {
        public static void ShowTest()
        {
            MessageBox.Show("Testmeldung");
        }
    }
}

Die DLL- Datei ist im richtigen Ordner und wird von dem Programm geladen.
An der Stelle an dem das Programm nun die Funktion ShowTest ausführen soll, gibt es nun ein Fehler:

http://www.onlinefirmenbuch.de/c-error.png

Ich haben in einem Thread gelesen, man solle die DLL, als Referenz einzubinden und diese in den Using mit einzufügen. Aber das ist unpraktisch für mein Projekt, da die DLL- Datei nicht unbedingt vorhanden ist und somit auch nicht eingebunden werden kann.


Ich danke allen Helfern schon mal im vorraus.
Mfg.: Zera
 
Schau die mal diese Links an:
http://dranaxum.wordpress.com/2008/02/25/dynamic-load-net-dll-files-creating-a-plug-in-system-c/
und
http://msdn.microsoft.com/de-de/library/system.reflection.assembly.aspx

Das Aufrufen der ShowTest-Methode alleine genügt nicht, denn, wie du schon selber schreibst, möchtest du mehrere DLLs dynamisch laden. Damit ist nicht mehr eindeutig, welche Methode gemeint ist (in welcher DLL soll nachgeschaut werden?).
Die DLL-Import Anweisung benötigst du nicht, denn das was du machen willst, ist ja DLLs dynamisch zu laden.
Habe folgenden Code nicht getestet sondern nur mehr oder weniger aus obigen Links abgeschrieben, aber ich hoffe der Ansatz wird klar:
C#:
Assembly u = Assembly.LoadFile("mod\\mod_mod.dll");
Type t = u.GetType("Class1");
MethodInfo m = t.GetMethod("ShowTest");
m.Invoke(null, null)
 
Zuletzt bearbeitet:
Ich danke dir Shakie für deine schnelle Antwort.
Doch gibt es nun ein weiteres Problem.

Die DLL- Datei ist unverändert und das Hauptprogramm schaut nun wie folgt aus:

Code:
        private void LoadStartOptions(object sender, EventArgs e)
        {
            Assembly u = Assembly.LoadFile(MainPath+ModPath+"\\mod_mod.dll");
            MethodInfo m = u.GetType("Class1").GetMethod("ShowTest");
            m.Invoke(null, null);
        }

Doch tritt nun der nächste Fehler auf:
http://www.onlinefirmenbuch.de/c-error1.png

Ich habe schon im Debug nachgesehen ob evtl die DLL- Datei nicht korrekt geladen wurde, doch es scheint als wäre alles ok.
Debug Information:
http://www.onlinefirmenbuch.de/img.png

Kann es an der Methode in der DLL- Datei liegen?

Ich versuche es selbst zum laufen zu bekommen, doch um weitere Hilfe wäre ich sehr dankbar.


Mir ist aufgefallen, dass nach der Zeile:
Code:
Type t = u.GetType("Class1");
t noch auf null steht





Shakie Ich danke dir nochmal für deine Hilfe.
Ich habe es nun geschafft das die Methode ausgeführt wird.

Hier meine Lösung:
Dll- Datei noch immer wie oben.
Hauptprogramm lädt (momentan nur eine DLL!) nun die DLL- Datei und führt die Methode aus:
Code:
private void LoadStartOptions(object sender, EventArgs e)
{

            Assembly u = Assembly.LoadFile(MainPath+ModPath+"\\mod_mod.dll");
            
            //Hole alle Typen der DLL- Datei
            Type[] Types = u.GetTypes();

            
            MethodInfo m = Types[0].GetMethod("ShowTest");
            m.Invoke(null, null);
}

Das Type Array deshalb, da man so alle Typen wie Resourcen und alle Klassen der DLL- Datei bekommt.
 
Zuletzt bearbeitet:
Freut mich, dass du's rausbekommen hast.
Vielleicht heißt der erste Typ in der Assembly nicht "Class1" sondern irgendwie anders (weiß nicht ob der Compiler tatsächlich die Klassennamen wie im Quellcode übernimmt oder noch irgendwas abändert).
Du musst aber aufpassen, falls du in deine DLL noch eine zweite Klasse reinpackst (oder eine Resource). Dann hat die Klasse mit der ShowTest-Methode nicht mehr unbedingt den Index 0. Wenn du also willst, dass andere Leute mods für dein Programm schreiben können sollen, dann müsstest du ihnen entweder sagen, dass der Typ mit Index 0 eine ShowTest-Methode haben muss.
Besser wäre vielleicht über alle Typen im Types-Array zu iterieren und überprüfen, ob sie eine ShowTest-Methode haben (wenn nicht, dann ist m==null). Wenn ja, dann rufst du Invoke auf.
 
Ich werfe mal folgendes in den Raum (habe sowas weder schon einmal gemacht, noch habe ich einen der Links gelesen):
Code:
Type t = u.GetType("mod_mod.Class1");

Wenn die Klasse in einem namespace steckt, müsste man es eigentlich so aufrufen.

Da ich das ganze doch nicht ohne Grund in den Raum werfen wollte, hab ich einfach ins msdn geguckt: http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx
For example, the fully qualified name for a class might look like this:
TopNamespace.SubNameSpace.ContainingClass+NestedClass,MyAssembly
 
Danke CPoly für deine Hilfe, doch ich habe es gestern schon geschafft zum laufen zu bekommen.

Ich habe nun ein anderes Problem mit dem laden der DLL- Datein.
Es gelang mit endlos viele DLL- Datein zu laden und dessen Resourcen zu laden um diese im Hauptprogramm darzustellen. Nun wollte ich der DLL- Datei ein Panel hinzufügen und entfernte das static von der Funktion die von dem Hauptprogramm in der DLL- Datai ausgeführt wird.

Sprich:
Code:
namespace mod_mod
{
    public class Class1
    {
        public static void ShowTest()
        {
            MessageBox.Show("Testmeldung");
        }
    }
}
Zu:
Code:
namespace mod_mod
{
    public class Class1
    {
        public void ShowTest()
        {
            MessageBox.Show("Testmeldung");
        }
    }
}

Doch gibt es wärend der Laufzeit nun den folgenden Fehler:
http://www.onlinefirmenbuch.de/c-error2.png

In StartMethod ist die Methode drinn:
Code:
MethodInfo m = Types[0].GetMethod("LoadModul");
StartMethod ist gleich m.

Ich würde schätzen das nun der Invoke Befehl abgeändert werden muss.
Ich trug als ersten Parameter den Ziel Typen ein doch ohne Erfolg.
Der Compiler meinte Der Zieltyp ist falsch.

Ich werde wie immer selbst versuchen das Problem zu lösen doch über eure Hilfe wäre ich sehr dankbar.
 
Ist dir bewusst, was "static" überhaupt bedeutet?
Du musst die Invoke-Methode natürlich auf einer Instanz der Klasse aufrufen, wie CPoly bereits geschrieben hat:
C#:
m.Invoke(instanz, null);
 

Neue Beiträge

Zurück