Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I return a char* string from C++ to C# in a Release build?

Tags:

I'm attempting to call the following trivial C function from C#:

SIMPLEDLL_API const char* ReturnString() {     return "Returning a static string!"; } 

With the following P/Invoke declaration (with or without the return attribute, it makes no difference):

[DllImport("SimpleDll")] [return: MarshalAs(UnmanagedType.LPStr)] public static extern string ReturnString(); 

It works if the DLL is a Debug build but crashes in a Release build (AccessViolationException).

I am calling over a dozen other simple functions and this is the only one that fails (here are the others:)

[DllImport("SimpleDll")] public static extern int NextInt(); [DllImport("SimpleDll")] public static extern void SetNextInt(int x); [DllImport("SimpleDll")] public static extern int AddInts(int a, int b); [DllImport("SimpleDll")] public static extern int AddFourInts(int a, int b, int c, int d); [DllImport("SimpleDll")] public static extern double AddDoubles(double x, double y); [DllImport("SimpleDll")] public static extern IntPtr AddDoublesIndirect(ref double x, ref double y); [DllImport("SimpleDll")] [return: MarshalAs(UnmanagedType.U1)] public static extern char CharStringArgument([MarshalAs(UnmanagedType.LPStr)]string s); [DllImport("SimpleDll")] [return: MarshalAs(UnmanagedType.U2)] public static extern char WCharStringArgument([MarshalAs(UnmanagedType.LPWStr)]string s); [DllImport("SimpleDll")] [return: MarshalAs(UnmanagedType.LPWStr)] public static extern string ReturnWString(); [DllImport("SimpleDll")] [return: MarshalAs(UnmanagedType.BStr)] public static extern string ReturnBSTR(); [DllImport("SimpleDll")] public static extern System.Drawing.Point MakePoint(int x, int y); [DllImport("SimpleDll")] public static extern IntPtr MakePointIndirect(int x, int y); [DllImport("SimpleDll")] public static extern int GetPointY(System.Drawing.Point p); [DllImport("SimpleDll")] public static extern int GetPointYIndirect(ref System.Drawing.Point pp); [DllImport("SimpleDll")] public static extern int SumIntegers(ref int firstElem, int size); 
like image 860
Qwertie Avatar asked Jun 09 '11 22:06

Qwertie


People also ask

Can char * be used as a return type in C?

Strings in C are arrays of char elements, so we can't really return a string - we must return a pointer to the first element of the string. All forms are perfectly valid. Note the use of const , because from the function I'm returning a string literal, a string defined in double quotes, which is a constant.

What does a char * function return?

This is because the function does not return a single character. Instead it returns an address which POINTS to a character (hence the name pointer), and it is denoted by a * .

What does char * mean in C?

In C programming language, *p represents the value stored in a pointer and p represents the address of the value, is referred as a pointer. const char* and char const* says that the pointer can point to a constant char and value of char pointed by this pointer cannot be changed.

How do I return a char pointer?

One solution is to allocate the appropriate amount of memory in the main function, and pass the pointer to the memory to the helper function. Show activity on this post. you shouldn't return data that sits on automatic storage, when you return it goes out of scope. scope and storage duration are two different beasts.


1 Answers

Or maybe try to use

[DllImport("SimpleDll")] public static extern IntPtr ReturnString(); 

and in your calling code, use the Marshal Class

string ret = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(PInvoke.ReturnString()); 
like image 54
Waleed Avatar answered Oct 06 '22 23:10

Waleed