Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

10.05.2017, 17:45

(Native) C++ Funktion von C# aufrufen

Hi,

ich habe versucht eine native C++-Funktion von C# aufzurufen.

So sieht meine C++-Funktion aus: (Die DLL heißt "cdll.dll" und die folgende Funktion ist in der Klasse "cdll.cpp"

C-/C++-Quelltext

1
2
3
4
int __declspec(dllexport) a(int b)
{
    return b;
}


Und so sah mein Versuch aus diese Funktion in C# aufzurufen

C#-Quelltext

1
2
3
4
5
6
7
[DllImport("cdll.dll", SetLastError = true)]
        public static extern int a(int b);

        static void Main(string[] args)
        {
            Console.WriteLine(a(5));
        }


So stand das auch im Internet und sollte so auch eigentlich richtig sein. Wenn ich nun aber diese Funktion ausführen möchte
bekomme ich folgenden Fehler:

Quellcode

1
2
3
4
An unhandled exception of type 'System.DllNotFoundException' occurred in c1.exe

Additional information: Die DLL "cdll.dll": Dieser Vorgang ist nur in einem Appcontainer-Kontext gültig.
(Ausnahme von HRESULT: 0x8007109A) kann nicht geladen werden.


Was hab ich falsch gemacht. Bei den Internet-Beispielen zu diesem Thema steht nie etwas zu Appcontainer-Kontexten?

mfg

2

10.05.2017, 18:20

Offensichtlich wird die Dll nicht gefounded. Beachte, dass VisualStudio das Arbeitsverzeichnis des Programmes auf das Projektverzeichnis legt, nicht auf das Programmverzeichnis. Lässt sich natürlich ändern.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

3

10.05.2017, 18:24

Ist das eien C++/CLI Bibliothek oder reines C++? Falls ich jetzt Mist erzähle möge man mich berichtigen. Um in .Net C++ Code aufzurufen muss es sich um C++/CLI handeln. Möchtest du reinen C++ Code aufrufen kannst du einen C++/CLI Wrapper basteln welchen du dann zum Beispiel aus C# heraus verwenden kannst. Du hast dann quasi:
C++ <-> C++/CLI <-> (C#, F#, VB.Net, ...)

Ich stecke da wie gesagt nicht wirklich im Thema. Kann sein dass der Fehler dann anders aussehen würde und in deinem Fall tatsächlich die Datei an sich nicht gefunden wird.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

4

10.05.2017, 19:12

Erstmal danke für eure Antworten!

An Schorsch:
Ja ich hab gehört das so ein C++ -> C++/CLI -> C++Native Wrapper möglich ist aber nicht notwerndig. Ich habe das so verstanden das man mithilfe P/Invoke auch direkt nativen C++-Code (also kein CLI) von C# aus ansprechen kann. Das ist ja was dass DllImport-Attribute macht. Damit kann man ja auch Funktion aus den nativen Windows-Dlls wie "user32.dll" oder "kernel.dll" benutzen.

An Techel:
Soweit ich dich richtig verstanden habe meinst du das sich die kompilierte C++-DLL im selben Ausgabeverzeichnis befinden muss wie das C#-Programm. Das ist aber bereits auch schon so. Hier mal ein Screenshots vom Ordner mit den ganzen Dateien:


(Link)


Ich weiß halt nicht warum es nicht funktioniert. Die DLL müsste gefunden werden sie kann aber nicht geladen werden wegen so nem AppContainer dabei ist es eine normale Windows-DLL kein Windows10 Universal Platform Schnick Schnack :D

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

5

11.05.2017, 09:33

Ja, GameXCraft, das mit DllImport hast du richtig verstanden.

Aber vielleicht überprüfst du dein C++ Projekt vielleicht noch mal, ob du nicht ausversehen doch den falschen Typ von DLL erzeugst?
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

6

11.05.2017, 18:17

An Legend

Hab die Antwort gefunden. Darauf muss man aber erst mal auch kommen wenn man sich nicht mit C++ auskennt. Man muss eine Konsolenanwendung erstellen und dort in diesem Vorbereitungsfenster dann angeben das es doch eine DLL sein soll.

Hab aber noch eine zweite Frage:
Ich habe jetzt versucht eine DLL mit MinGW zu erstellen und diese dann im C#-Projekt zu benutzen.

Das ist der aktuelle Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

#include <iostream>
using namespace std;

extern "C"
__declspec(dllexport)
int
__cdecl
test(int a) {
    return a + 1;
}


Und diese beiden Kommandozeilen benutze ich um die DLL zu erstellen:

Quellcode

1
g++ -c example_dll.cpp

Quellcode

1
g++ -shared -o test.dll test.o -Wl,--subsystem,windows


Funktioniert sogar. Die DLL ist im C#-Build-Ordner (Also bin/release).
Aber wenn ich jetzt das C#-Programm starte kommt folgende Fehlermeldung:

Unbehandelte Ausnahme: System.BadImageFormatException: Es wurde versucht eine Datei mit einem falschen Format zu laden (Ausnahme von HRESULT: 0x8007000B)

Was ist jetzt falsch?

mfg

birdfreeyahoo

Alter Hase

Beiträge: 756

Wohnort: Schorndorf

Beruf: Junior Software Engineer

  • Private Nachricht senden

7

11.05.2017, 23:57

Afaik ein 32/64-Bit Konflikt. Für welche Plattformen kompilierst du jeweils?

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

8

12.05.2017, 09:39

Ich würde auch auf ein Problem bzgl. 32 und 64 Bit tippen.
Das kommt auch schneller als man denkt. Kompilierts du dein C# Programm für die Platform Any CPU?
Auf einem 64 Bit Windows wird dann ein 64 Bit Prozess gestartet, der natürlich keine 32 Bit unmanaged DLLs laden kann.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

9

13.05.2017, 16:43

Das ist natürlich möglich dass, das ein 32/64-Bit-Problem ist. Und ja als Platform wurde "Any CPU" gewählt.

Ich habe es jetzt so versucht auf 32-Bit umzustellen

(Link)


Wirft aber immer noch einen BadImageFormat-Fehler :|

Werbeanzeige