Jsncrdnl
Jsncrdnl

Reputation: 3075

How to pass strings from C# to C++ (and from C++ to C#) using DLLImport?

I've been trying to send a string to/from C# to/from C++ for a long time but didn't manage to get it working yet ...

So my question is simple :
Does anyone know some way to send a string from C# to C++ and from C++ to C# ?
(Some sample code would be helpful)

Upvotes: 26

Views: 37997

Answers (3)

Samy Arous
Samy Arous

Reputation: 6812

Passing string from C# to C++ should be straightforward - PInvoke will manage the conversion for you.

Getting a string from C++ to C# can be done using a StringBuilder. You need to get the length of the string in order to create a buffer of the correct size.

Here are two examples of a well-known 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!");

Upvotes: 14

sithereal
sithereal

Reputation: 1686

in your c code:

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

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

at .net side:

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);

Upvotes: 21

noonand
noonand

Reputation: 2865

A lot of functions that are encountered in the Windows API take string or string-type parameters. The problem with using the string data type for these parameters is that the string datatype in .NET is immutable once created so the StringBuilder datatype is the right choice here. For an example examine the API function 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);

Upvotes: 1

Related Questions