c++ cstring to c# string
-
Hallo,
ich habe ein Problem undzwar möchte ich gern von einem Kollegen eine c++ dll in mein c# Projekt implementieren.
Das ist mein Projekt, funktoniert soweit auch:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; // wichtig für DllImport namespace dllimport { public partial class Form1 : Form { // Externe dll-Funktion Importieren [DllImport("C:\\Dokumente und Einstellungen\\Azubi\\Desktop\\test.dll", CharSet = CharSet.Auto)] //Hier wird die DDL statisch von einem Speicherort geladen. protected static extern void test(); // protected static extern + typ + methodenname // Methode die es ermöglicht von C# aus auf die dll // zuzugreifen public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { test(); // aufruf der DLL methode } } }
Nun möchte ich aber eine DLL einbinden, welche einen Text zurückliefert, also einen "Cstring", jedoch kann ich in c# damit nicht viel anfangen.
Habe versucht mit "char" zu arbeiten, jedoch bekomme ich dann nur ein merkwürdiges sonderzeichen von der DLL zurück.
Mit einem char array oder dem normalen string als datentyp kam ich leider auch nicht weiter.
Code der C DLL:
__declspec (dllexport) CString testzwei(CString master) { MessageBox(NULL, master, _T("Übergebener Wert aus deinem CString!"), MB_OK); return _T("OK, das wars..."); }
Wäre super wenn mir jemand weiter helfen könnte.
-
Mal ein bisschen gegoogelt...
Evtl. hilft dir das weiter: http://www.codeguru.com/forum/showthread.php?t=354197
-
Servus,
probier das mal:
using System.Runtime.InteropServices; [return: MarshalAs(UnmanagedType.LPWStr)] [DllImport("C:\\Dokumente und Einstellungen\\Azubi\\Desktop\\test.dll", CharSet = CharSet.Auto)] protected static extern string test();
gruß
Hellsgore
-
Danke an euch, jedoch komme ich damit trotzdem nicht weiter..
@ Hellsgore:
Dein Code war ja ohne Parameter aufruf..
Die frage ist nun welchen Datentyp soll ich denn für cstring verwenden ?Wenn ich deinem Beispiel folge müsste ich meinem Quellcode so aufbauen:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; // wichtig für DllImport namespace dllimport { public partial class Form1 : Form { [return: MarshalAs(UnmanagedType.LPWStr)] // Externe dll-Funktion Importieren [DllImport("C:\\Dokumente und Einstellungen\\Azubi\\Desktop\\test4.dll", CharSet = CharSet.Auto)] //Hier wird die DDL statisch von einem Speicherort geladen. protected static extern string testzwei(string test); // protected static extern + typ + methodenname // Methode die es ermöglicht von C# aus auf die dll // zuzugreifen public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { string x = testzwei("test"); label1.Text = x; } } }
Jedoch bekomme ich dann in der Messagebox ein zufälliges ASCII zeichen ausgegeben, jedoch nicht so wie es sein sollte meinen übergebenen Parameter.
Und meine Anwendung bricht danach zusammen.
Wäre super wenn du mir das noch einmal einwenig erläutern könntest.
(Bin leider auch kein C# crack, sondern eher anfängerlevel)
-
Servus,
mir ist gerade eingefallen, dass du nicht einfach einen CString auf einen C# string marshallen kannst. Es gibt dort ein paar Kniffe und Tricks, mit denen du das bewerkstelligen kannst. (Stichwort: Struct als CString übergeben und mit PtrToStr arbeiten) Ist aber alles etwas umständlich. Du könntest z.B. in deiner C++ dll einen char* oder ein LPSTR / LPWSTR verwenden. Ein casten auf einen CString, wenn du denn die Methoden von CString verwenden willst, sollte ein Einfaches sein.
Damit dein Vorhaben funktioniert, solltest du folgendes machen:
C++ DLL
__declspec (dllexport) LPWSTR testzwei(LPWSTR master) { MessageBox(NULL, master, _T("Übergebener Wert aus deinem LPWSTR!"), MB_OK); return _T("OK, das wars..."); }
C#
[DllImport("Test.dll", EntryPoint = "testzwei", CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.LPWStr)] protected static extern string testzwei([MarshalAs(UnmanagedType.LPWStr)] string master);
Dann klappts auch mit dem Nachbarn
Möchtest du mehr zu dem Thema PInvoke bzw. Marshallen erfahren, dann kannst du folgenden Links folgen:
http://www.pinvoke.net/
http://www.codeproject.com/KB/dotnet/PInvoke.aspx
http://www.codeproject.com/KB/cs/essentialpinvoke.aspx
http://msdn.microsoft.com/de-de/library/aa446536.aspxoder einfach
http://www.google.de/search?hl=de&q=pinvoke+c%23&btnG=Suche&meta=Dort wird dir alles was du für die Anfänge benötigst, beschrieben...
gruß
Hellsgore
-
cool..
Super vielen Dank werds testen und mir die links mal zu gemüte führen und studieren