Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)

like image 796
Jsncrdnl Avatar asked May 29 '12 12:05

Jsncrdnl


People also ask

How do you pass strings?

To pass a string by value, the string pointer (the s field of the descriptor) is passed. When manipulating IDL strings: Called code should treat the information in the passed IDL_STRING descriptor and the string itself as read-only, and should not modify these values.

How do you pass a string to a function syntax?

To pass a one dimensional string to a function as an argument we just write the name of the string array variable. In the following example we have a string array variable message and it is passed to the displayString function.

How do you print a string in C?

using printf() If we want to do a string output in C stored in memory and we want to output it as it is, then we can use the printf() function. This function, like scanf() uses the access specifier %s to output strings. The complete syntax for this method is: printf("%s", char *s);

How do you pass a string by reference?

Pass String by Reference in C++ The C++ reference is a name for a variable that already exists. A reference to a variable can't be altered to refer to the other variable once initialized. Pointers or references can be passed as parameters to functions in C++.


3 Answers

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

Geting 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!");
like image 27
Samy Arous Avatar answered Oct 20 '22 07:10

Samy Arous


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);
like image 89
sithereal Avatar answered Oct 20 '22 06:10

sithereal


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);
like image 1
noonand Avatar answered Oct 20 '22 05:10

noonand