PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Quasitreiber im Selbstbauversuch C# mit .NET



Ceos
19.09.2011, 12:26
nachdem ich im Cplusplus-Forum leider vergleblich auf Antwort warte, hoffe ich hier vielleicht jemanden mit Erfahrung auf dem Gebiet anzutreffen

Ich versuche gerade einen Quasi-Treiber als DLL zu schreiben, welchen ich dann später in Labview einbauen möchte, da ich mit Labview in der Beziehung auf Kriegsfuß stehe!

Der Plan ist recht simpel aber Umständlich (Labview lernen wäre noch umständlicher) ...

Eine DLL mit Interfacemethoden und einer Load-Methode, welche in Labview statisch eingebunden wird. Zur Laufzeit wird die eigentliche Treiber-DLL via Load-Methode nachgeladen und über die Interfacemethoden durch Vererbung auf den Treiber zugegriffen.

Sieht nach ersten versuchen folgendermaßen aus:

TestDLL.DLLClass libraryobject = null;
Assembly DLLLink = null;
public bool loadDLL(string path)
{
try
{
DLLLink = Assembly.LoadFrom(path);
Type t = DLLLink.GetType("TestDLL.DLLClass");
libraryobject = (TestDLL.DLLClass)Activator.CreateInstance(t); //<---- hier steigt er aus
return true;
}
catch (Exception e)
{
textBox1.AppendText(e.Message+"\r\n");
}
return false;
}


produziert aber folgenden Fehler den ich nicht zu entschlüsseln vermag (auch leider in Google nichts nützliches entdeckt)


TestDLL.dll
[A]TestDLL.DLLClass kann nicht in [B]TestDLL.DLLClass umgewandelt werden. Der Typ "A" stammt von "TestDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" im Kontext "LoadFrom" am Speicherort "TestDLL.dll".. Der Typ "B" stammt von "TestDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" im Kontext "Default" am Speicherort "TestDLL.dll"..


falls jemand eine Idee hat wie genau man den Fehler zumindest interpretieren kann oder einen nützlichen Link findet, her damit ich bin Dankbar für alles!

Die Objekte unterscheiden sich ja nur im "Kontext" wie ich den aber manipulieren kann oder wie ich es richtig mache sag einem aber leider keiner. Mein Code ist aus Beispielen im Netz abgeleitet um DLLs dynamisch nachzuladen!

PicNick
19.09.2011, 14:31
Kann bei C# nicht viel sagen, aber wenn eine DLL nicht passt, geht es meistens um den "call"-Standard.

Bei C++ muss ich sowas definieren


class RNREGIST_API CRnRegist {
public:
CRnRegist(void);
};

extern "C" RNREGIST_API int fnRnRegist(void);


damit die DLL allgemein verwendbar ist ( also für Visial Basic oder sonstwas)

VIelleicht gilt das auch für labview

Ceos
19.09.2011, 15:33
den gibts in c# nicht mehr, .net nimmt mir freundlicherweise die ganzen entrypointdefinitionen ab!

Das Problem tritt interessanterweise nur dann auf, wenn ich eine DLL versuche doppelt zu laden ... ich habe bis jetzt keine Idee wie ich genau das verhindern kann!

Wenn ich die abgeleitete DLL direkt lade funktioniert der cast wunderbar, wenn ich dann aber irgendwann einmal die Basis DLL doppelt geladen habe(verklickt oder eben provoziert), kann er nichtmehr casten!

Der Fehler basiert allerdings auf dem Fehler im ersten Post, sobald ich 2 mal die Basis-DLL geladen habe kann er nichtmehr auf die Basisklasse runtercasten!

Ceos
19.09.2011, 16:49
okay, sry für doppelpost aber ich habs gelöst ^^

ich musste zwar komplett über die reflections-API gehen, was mir einige scherereien besorgt hat, aber da ich das alles nur in der Basisklasse einmal tippen muss iss mir das Sch***egal (selbstzensiert) ^^

Ich erkläre nur eben den Weg, den Code zu posten wäre vll. etwas krass ^^ aber wenn Bedarf besteht einfach melden, ich heb sowas ewig auf ^^

Ich rufe in Labview die DLL auf,
erzeuge mir ein Objekt der Basisklasse,
rufe die load-Methode auf,
übergeb ihr den Pfad zur abgeleiteten DLL,
suche im Verzeichnis der abgeleiteten DLL nach der Basis-DLL (um sie über Reflections zu öffnen),
prüfe ob die DLL bereits geladen wurde und hole sie ggf. aus dem cache ODER
öffne dann die abgeleitete DLL über Reflections, prüfe ob es die Basis-DLL ist und weise sie ggf. ab, ODER lade die neue DLL in den cache
dann caste ich sie noch auf die Basisklasse herunter (klappt jetzt, weil ich die base-dll nur über reflection lade)

über die anfangs angelegte basis-Instanz kann ich dann über die public Methoden indirekt auf die abgeleiteten Funktionen zugreifen!

shedepe
19.09.2011, 16:53
Bei solchen C# spezifischen Fragen lohnt sich immer ein Blick auf www.mycsharp.de (http://www.mycsharp.de) .Ich denke mal dass man dir dort eher weiter helfen kann als hier.
Ich könnte mir vorstellen, dass wenn du die Dll zwei mal geladen hast, dass die Reflection Probleme hat verschiedene Verweise aufzulösen, da nun [A] und [B] zur Verfügung stehen in denen allerdings die gleichen Klassen usw. definiert sind.

EDIT: Gut wenn dus selber gelöst hast. Ich hätte noch interesse am Code

Ceos
19.09.2011, 17:28
schick ich dir morgen wenn ich wieder am rechner sitze flüster mir mal ne mail, weil das relativ viel text iss hier als code

shedepe
19.09.2011, 18:37
Häng es doch einfach als Txt oder als .cs datei in den Anhang. Ich werd dir trotzdem mal meine Mail per PN schicken