myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Basistechnologien und allgemeine .NET-Klassen » Wie kann ich Klassen aus C++ DLL oder die DLL mehrfach laden?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Wie kann ich Klassen aus C++ DLL oder die DLL mehrfach laden?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
matrix4you
myCSharp.de-Mitglied

Dabei seit: 26.03.2020
Beiträge: 5


matrix4you ist offline

Wie kann ich Klassen aus C++ DLL oder die DLL mehrfach laden?

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Halli-hallo,

ich habe eine DLL welche in c++/c erstellt ist. In dieser sind Funktionen und eine Klasse definiert. Die Funktionen kann ich ohne Probleme in meinem c# Programm nutzen. Das Funktioniert auch alles prima. Zum Hintergrund: In der DLL befindet sich alles was ich benötige um bestimmte Geräte per USB Kabel zu programmieren. Leider kann ich mit der DLL immer nur ein Gerät programmieren. Mit der Klasse wäre es möglich mehrere Geräte parallel zu flashen. Leider bekomme ich es nicht hin. Wenn ich mein Programm mehrfach starte laufen die Programmiervorgänge ohne Probleme da die DLL in jedem Thread eigens geladen wird. Habe nur die Header Datei (aus ihr hab ich den c# code abgeleitet) und die DLL.

Nun hatte ich folgende Ideen, leider funktioniert keine oder mir fehlt einfach das nötige Know-How:
  • Versucht die Klasse zu nutzen in c#
  • Versucht die dll in Threads mehrfach zu laden
  • Die Klasse in einem c++ Programm zu nutzen um evtl. eine zwischen DLL zu nutzen die mir hilft. (Leider klappt da das nutzen der DLL schon nicht da ich keine lib Datei habe und das generieren auch nicht funktionierte da ich die ordinal von der Klasse nicht raus bekam)
Falls mir jemand helfen möchte oder eine Idee für mich hat dann freue ich mich sehr.

Viele Grüße,
Björn

.h (Auszug)

Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
//funktioniert
short __declspec(dllimport) CALLBACK nbl_ReadPID(uint8 *Name = NULL, uint8 MaxLen = 0);

//funktioniert nicht oder ich weiß nicht wie
typedef class __declspec(dllimport) Usb2Lin
{
public:
   Usb2Lin();
   ~Usb2Lin();
      short CALLBACK nbl_ReadPID(uint8 *Name = NULL, uint8 MaxLen = 0);
} tUsb2Lin;

Also habe ich für die Funktion folgendes genutzt:
c#

C#-Code:
  //so lade ich die dll
        [DllImport("Usb2LinDll.dll")]
        public static extern short nbl_ReadPID(StringBuilder Name, byte MaxLen = 0);
Neuer Beitrag 29.07.2020 22:30 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.677
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo und willkommen,

der DllImport bei der globalen Funktion funktioniert, weil diese entweder mit einem C-Compiler übersetzt wurde oder aber bei C++ zusätzlich noch innerhalb von extern "C" { ... } steht, d.h. da findet dann kein  Name Mangling statt und der Funktionsaname kann 1:1 von C# aus übernommen werden (Beispiel:  Import function from unmanaged C++ DLL).
Eine Klasse bzw. (nicht-statische) Klassenfunktion kannst du nicht direkt benutzen, da du den genauen "gemangelten" Namen dafür benötigst, s. z.B.  Using Unmanaged C++ Libraries (DLLs) in .NET Applications.

Eine m.E. bessere Alternative ist die Verwendung von  C++/CLI zur Erzeugung einer Interop-Assembly, s. z.B.  How to Marshal a C++ Class ("Solution B: Create a Bridge DLL in Managed C++"). [Evtl., wenn du C bzw. C++ kannst, wäre auch "Solution A: Create Bridge Functions in C and Use PInvoke" möglich - ein weiteres Beispiel dafür gibt es unter  using a class defined in a c++ dll in c# code]
Dort kannst du direkt native und .NET-Funktionalität mixen. Aber auch dort würdest du sinnvollerweise die ".lib"-Datei benötigen (sonst hast du per LoadLibrary und GetProcAddress dasselbe Problem bzgl. Name-Mangling!).
Wie wird denn bisher die DLL benutzt?

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am 30.07.2020 08:18.

Neuer Beitrag 30.07.2020 08:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
matrix4you
myCSharp.de-Mitglied

Dabei seit: 26.03.2020
Beiträge: 5

Themenstarter Thema begonnen von matrix4you

matrix4you ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

vielen Dank für die Ausführliche Erklärung die mir Klarheit verschafft hat. Werde ich durcharbeiten.

Ja die Funktionen sind extern "C" deklariert das stimmt.

Mit dem dumpbin habe ich das Problem das ich den Konstruktor und De-Konstruktor nicht richtig bekomme oder erkenne. Die DLL ist sicher nicht mit .net erstellt. Versuche aber noch mal den weg mit DllImport und EntryPoint. Hatte bis jetzt versucht selbst eine LIB zu erstellen.

Die DLL wird bis jetzt in kleinen Tools benutzt die dann die Firmware oder Konfig auf der Hardware aktualisieren. Wir brauchen jetzt aber ein Tool welches mehrere Endgeräte gleichzeitig aktualisiert. Wie gesagt leider habe ich nicht mehr zur Verfügung. Der Tools und DLL Entwickler ist alles andere als eine Hilfe. Wir haben uns so über den DllImport schon einige kleine eigene Tools gebastelt. Leider kann ich über die Funktionen immer nur eine Hardware ansprechen. Außer die Programme laufen zwei mal.

Die Idee die DLL in mehreren Instanzen laufen zu lassen und die Klasse auszulassen ist keine Gute Idee, oder was denkst Du zu der Alternative?

Danke noch mal...
Grüße, Björn

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von matrix4you am 31.07.2020 07:41.

Neuer Beitrag 31.07.2020 07:39 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.677
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Mit "Wie wird denn bisher die DLL benutzt?" meinte ich dies eher technisch, also wie wird ohne ".lib"-Datei diese überhaupt benutzt?

DLLs können technisch nicht mehrfach von einem Prozess geladen werden (zumindestens bei statischer Einbindung), s.a.  Load the same dll multiple times -> du müßtest also LoadLibrary verwenden und jeweils die DLL unter einem anderen Namen öffnen (kein guter Ansatz!).

Edit:
Und direkt kann ein Objekt (Instanz) einer C++ Klasse nicht von C# aus (per P/Invoke) erzeugt werden, auch dafür bräuchtest du eine native freie (in C++ oder C++/CLI) geschriebene Funktion, welche ein Objekt erzeugt und als Zeiger zurückgibt (per new).
Selbiges gilt für das Freigeben des Objekts (per delete).
s.a.  Create unmanaged c++ object in c#.

Sorry für die vielen Links, aber das ist ein technisch anspruchsvolles Thema, das man nicht mit ein paar Sätzen und Codezeilen erklären kann.

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Th69 am 31.07.2020 08:24.

Neuer Beitrag 31.07.2020 08:14 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
matrix4you
myCSharp.de-Mitglied

Dabei seit: 26.03.2020
Beiträge: 5

Themenstarter Thema begonnen von matrix4you

matrix4you ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ach so sorry. Ohne c/c++ oder LIB, ich habe die DLL als Verweis in c# hinzugefügt und die benötigten Funktionen die als extern "C" angegeben sind alle so wie oben beschrieben bekannt gemacht. Die Definitionen habe ich abgeleitet von der Header Datei:

C#-Code:
[DllImport("Usb2LinDll.dll")]
public static extern short nbl_ReadPID(StringBuilder Name, byte MaxLen = 0);
[DllImport("Usb2LinDll.dll")]
public static extern short nextFunction ... usw.

Danach nutze ich die Funktionen ganz normal. Wie gesagt bis dahin brauche ich die Klasse auch gar nicht.

Schade, dachte es mir fast das es nicht möglich ist die DLL mehrfach zu nutzen über einen sauberen und schönen Weg. Das ergaben auch meine Tests.

Hey, ich bin so Mega Dankbar für Deine Hilfe da gibt es keinen Grund das Du Dich entschuldigen musst. Die Links sind sehr Hilfreich. Danke noch mal.
Neuer Beitrag 31.07.2020 09:23 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.677
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Bist du denn der einzige Benutzer dieser DLL? Und warum kann der DLL-Entwickler (ist das ein Kollege?) denn nicht die ".lib" zur Verfügung stellen (nur die Headerdatei herauszugeben ist ja dann (fast) sinnlos)?
Und frage ihn, ob er nicht die beiden Funktionen zum Erzeugen und Freigeben des Klassenobjekts gerade implementieren kann (sind ja nur jeweils ein paar Zeilen) - sag ihm, daß du sonst mit der C++ Klasse nichts anfangen kannst (du kannst ihm ja auch die Artikel zeigen).

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am 31.07.2020 10:00.

Neuer Beitrag 31.07.2020 09:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
matrix4you
myCSharp.de-Mitglied

Dabei seit: 26.03.2020
Beiträge: 5

Themenstarter Thema begonnen von matrix4you

matrix4you ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Nee benutzen tun die noch andere aber ich bin der einzige an unserem Standort der die in eigenen Programmen nutzt. Du das Problem ist der Kollege sitzt in Dänemark und die Dänen sind alles andere als Leute die gut zuarbeiten. Ich werde aber noch mal dort anklopfen und fragen ob sie nicht mal einen Schritt auf uns zu machen mögen.
Neuer Beitrag 31.07.2020 12:08 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Spook Spook ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.10.2008
Beiträge: 214
Entwicklungsumgebung: VS2019
Herkunft: Esslingen a.N.


Spook ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo matrix4you,

was spricht gegen das Erstellen einer Wrapper DLL wie bereits vorgeschlagen wurde?
Ich würde dies als sinnvollen und umsetzbaren Lösungsweg ansehen.
Das gelinkte Beispiel macht 1 zu 1 was du brauchst.

Hast du von der verwendeten DLL die .h und die .lib Dateien?
Was hast du schon in die Richtung versucht?

PS: Wenn die DLL eine native C/C++ DLL ist, dann macht es wenig Sinn diese als Verweis hinzuzufügen.


Grüße
spooky

edit: Typo

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Spook am 31.07.2020 12:51.

Neuer Beitrag 31.07.2020 12:50 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
matrix4you
myCSharp.de-Mitglied

Dabei seit: 26.03.2020
Beiträge: 5

Themenstarter Thema begonnen von matrix4you

matrix4you ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo spooky,

ja das mache ich. Bin gerade dran die lib zu bekommen. Wie ich schrieb habe ich diese ja nicht und nur die .h.

Danke noch mal an Th69

Grüße
Björn
Neuer Beitrag 04.08.2020 07:07 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 13.08.2020 17:14