Как передать строки из C # в C ++ (и из C ++ в C #), используя DLLImport?

Я давно пытался отправить строку в / из C # в / из C ++, но пока не удалось заставить ее работать ...

Так что мой вопрос прост:
Кто-нибудь знает способ отправки строки из C # в C ++ и из C ++ в C #?
(Некоторый пример кода будет полезен)

Ответы на вопрос(3)

Решение Вопроса

Передача строки из C # в C ++ должна быть прямой. PInvoke будет управлять преобразованием для вас.

Получение строки из C ++ в C # может быть сделано с помощью StringBuilder. Вам нужно получить длину строки, чтобы создать буфер правильного размера.

Вот два примера хорошо известного Win32 API:

[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!");

встречающиеся в Windows API, принимают строковые или строковые параметры. Проблема использования строкового типа данных для этих параметров заключается в том, что строковый тип данных в .NET является неизменяемым после создания, поэтому тип данных StringBuilder является правильным выбором. Для примера рассмотрим функцию API GetTempPath ()

Windows API definition

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

.NET prototype

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

Usage

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

в вашем коде c:

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

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

на стороне .net:

using System.Runtime.InteropServices;


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

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

использование:

SetString("hello");
StringBuilder rntStr = new StringBuilder();
GetString(rntStr);
 29 мая 2012 г., 15:22
@Ben Voigt: спасибо, исправил.
 29 мая 2012 г., 15:20
Вашconst использование в обратном направлении.
 13 янв. 2017 г., 17:04
Эти примеры разбирались с исключениями стека в VisStudio 2012, пока я не добавил cdecl и в C #, и в C .... extern & quot; C & quot; __declspec (dllexport) int __cdecl SetString (... и затем ... [DllImport (& quot; YourLib.dlll & quot ;, CallingConvention = CallingConvention.Cdecl)] ...

Ваш ответ на вопрос