web-dev-qa-db-fra.com

Comment passer des chaînes de C # à C ++ (et de C ++ à C #) à l'aide de DLLImport?

J'essaye d'envoyer une chaîne de/de C # à/de C++ depuis longtemps mais je n'ai pas encore réussi à le faire fonctionner ...

Ma question est donc simple:
Quelqu'un connaît-il un moyen d'envoyer une chaîne de C # vers C++ et de C++ vers C #?
(Un exemple de code serait utile)

21
Jsncrdnl

Passer une chaîne de C # à C++ devrait être simple. PInvoke gérera la conversion pour vous.

L'obtention d'une chaîne de C++ vers C # peut être effectuée à l'aide d'un StringBuilder. Vous devez obtenir la longueur de la chaîne afin de créer un tampon de la taille correcte.

Voici deux exemples d'une API Win32 bien connue:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
public static string GetText(IntPtr hWnd)
 {
     // Allocate correct string length first
     int length       = GetWindowTextLength(hWnd);
     StringBuilder sb = new StringBuilder(length + 1);
     GetWindowText(hWnd, sb, sb.Capacity);
     return sb.ToString();
 }


[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
 public static extern bool SetWindowText(IntPtr hwnd, String lpString);
SetWindowText(Process.GetCurrentProcess().MainWindowHandle, "Amazing!");
12
Samy Arous

dans votre code c:

extern "C" __declspec(dllexport)
int GetString(char* str)
{
}

extern "C" __declspec(dllexport)
int SetString(const char* str)
{
}

côté .net:

using System.Runtime.InteropServices;


[DllImport("YourLib.dll")]
static extern int SetString(string someStr);

[DllImport("YourLib.dll")]
static extern int GetString(StringBuilder rntStr);

usage:

SetString("hello");
StringBuilder rntStr = new StringBuilder();
GetString(rntStr);
21
sithereal

De nombreuses fonctions rencontrées dans l'API Windows acceptent des paramètres de type chaîne ou chaîne. Le problème lié à l'utilisation du type de données chaîne pour ces paramètres est que le type de données chaîne dans .NET est immuable une fois créé, le type de données StringBuilder est donc le bon choix ici. Pour un exemple, examinez la fonction API GetTempPath ()

définition de l'API Windows

DWORD WINAPI GetTempPath(
  __in   DWORD nBufferLength,
  __out  LPTSTR lpBuffer
);

prototype. NET

[DllImport("kernel32.dll")]
public static extern uint GetTempPath
(
uint nBufferLength, 
StringBuilder lpBuffer
);

tilisation

const int maxPathLength = 255;
StringBuilder tempPath = new StringBuilder(maxPathLength);
GetTempPath(maxPathLength, tempPath);
1
noonand