Brauche Hilfe bei unmanaged C++ Code und C++/CLI Wrapper in C#

Gast #3911217
Lesenswert?
• ▲
▼
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
Gast #3911633
Lesenswert?
• ▲
▼
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.
Gast #3912618
Lesenswert?
• ▲
▼
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
}
#3912690
Lesenswert?
• ▲
▼
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ß.
Gast #3912886
Lesenswert?
• ▲
▼
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren