Hallo, hoffe jemand kann mir helfen. Habe nach dieser Anleitung meinen unmanaged C++ Code über einen C++/CLI Wrapper in mein C# Projekt eingebunden. http://drthitirat.wordpress.com/2013/06/03/use-c-codes-in-a-c-project-wrapping-native-c-with-a-managed-clr-wrapper/ Funktioniert auch, allerdings verwenden meine Funktionen in C++ einen Parameter const char*: C++ [code} float Funcs::ValueFunction(const char* filename, int num) { .... return a; } [/code} Im C++/CLI Wrapper passiert eigentlich nichts. In C# kann ich auf die Funktion auch zugreifen, allerdings wird mir der Parameter der Funktion als sbyte* angezeigt und meinen C# string kann ich ja nicht damit nutzen. Kann mir jemand ein gutes Beispiel senden? Habe schon einiges über marshal gelesen, aber kein gutes Beipiel gefunden. Danke
Danke, leider hat mich das noch nicht weiter gebracht. Ich lade heute Abend mal ein Beispiel hier hoch. Möchte gerne den C++/CLI wrapper nutzen und nicht die unmanaged C++ DLL in C# laden, wie in dem verlinkten Beispiel. PS: Auch wenn ich im nativ C++ Code strings in der Funktion nutze und die Funktion über den Wrapper an C# weitergeben kann ich keinen String als Parameter an die Funktion übergeben. Ich stehe irgendwie mit den Datentypen aufm Schlauch.
Hallo, die Konvertierung vom C# String zu char* muss ich im Wrapper durchführen oder? So wie unten funktioniert der C# Code natürlich nicht. SimpleFunctions.h
1 | #pragma once |
2 | #include <stdexcept> |
3 | |
4 | using namespace std; |
5 | |
6 | class MySimpleFunctions { |
7 | public: |
8 | int TextOK(const char* text); |
9 | }; |
SimpleFunctions.cpp
1 | #pragma once |
2 | #include "SimpleFunctions.h" |
3 | |
4 | int MySimpleFunctions::TextOK(const char* text) { |
5 | int a = 0; |
6 | |
7 | if (text == "Hello") |
8 | a = 1; |
9 | else |
10 | a = 2; |
11 | |
12 | return a; |
13 | } |
nativeCppWrapper.h
1 | // nativeCppWrapper.h |
2 | |
3 | #pragma once |
4 | |
5 | #include "SimpleFunctions.cpp" |
6 | #include "SimpleFunctions.h" |
7 | |
8 | using namespace System; |
9 | |
10 | namespace nativeCppWrapper { |
11 | public ref class MySimpleFunctionsWrapper |
12 | { |
13 | public: |
14 | MySimpleFunctionsWrapper(); |
15 | int TextOK(const char* text); |
16 | |
17 | private: |
18 | MySimpleFunctions *myCppClass; |
19 | }; |
20 | } |
nativeCppWrapper.cpp
1 | // This is the main DLL file. |
2 | |
3 | #include "stdafx.h" |
4 | #include "nativeCppWrapper.h" |
5 | |
6 | nativeCppWrapper::MySimpleFunctionsWrapper::MySimpleFunctionsWrapper() |
7 | { |
8 | myCppClass = new MySimpleFunctions(); |
9 | } |
10 | |
11 | int nativeCppWrapper::MySimpleFunctionsWrapper::TextOK(const char* text) |
12 | { |
13 | return myCppClass->TextOK(text); |
14 | } |
Form1.cs
1 | using System; |
2 | using System.Collections.Generic; |
3 | using System.ComponentModel; |
4 | using System.Data; |
5 | using System.Drawing; |
6 | using System.Linq; |
7 | using System.Text; |
8 | using System.Threading.Tasks; |
9 | using System.Windows.Forms; |
10 | using nativeCppWrapper; |
11 | |
12 | namespace CsharpApp |
13 | { |
14 | public partial class Form1 : Form |
15 | { |
16 | MySimpleFunctionsWrapper myFunction = new MySimpleFunctionsWrapper(); |
17 | public Form1() |
18 | { |
19 | InitializeComponent(); |
20 | } |
21 | |
22 | private void button1_Click(object sender, EventArgs e) |
23 | { |
24 | String str = "Hello"; |
25 | int x = myFunction.TextOK(str); |
26 | } |
27 | } |
28 | } |
Der CLI-Wrapper sollte einen .net-String entgegennehmen und zwar per Referenz: MySimpleFunctionsWrapper::TextOK(String% txt) So kann C# die Methode ganz einfach als TextOK("text") aufrufen. Dann mußt Du den String entweder mit dem gewünschten Encoding in ein Byte-Array schreiben (das kannst Du auch erstmal in C# üben) oder Dir den Zeiger auf die interne UTF-16 Representation geben lassen. Das Netz ist voll von Beispielen dazu, weil es ja auch wirklich eine immer wiederkehrende nervige Aufgabe ist. Siehe z.B. hier: http://support.microsoft.com/kb/311259 Wichtig ist, zu verstehen warum und wann man Pinnen muß bzw. wann man GC.keepalive() benutzen muß.
Danke für den Tipp. Kann jetzt die Funktion richtig aufrufen, allerdings wird der String nicht korrekt übergeben. Zumindest bekomme ich nicht das korrekte Ergebnis von der Funktion geliefert.
1 | int nativeCppWrapper::MySimpleFunctionsWrapper::TextOK(String^ text) |
2 | { |
3 | using namespace Runtime::InteropServices; |
4 | const char* str = (const char*)(Marshal::StringToHGlobalAnsi(text)).ToPointer(); |
5 | return myCppClass->TextOK(str); |
6 | Marshal::FreeHGlobal(IntPtr((void*)str)); |
7 | } |
Ok, funktioniert alles ;) Hatte noch einen anderen Fehler. Danke!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.