I have a C++ function that I am trying to return a const char * pointer to C#. I know about interop and have other functions that return int's and those work. Can C# receive const char * pointers from C++?
Re: Returning a const char * pointer from C++ to C#?
Originally Posted by wwuster
I have a C++ function that I am trying to return a const char * pointer to C#. I know about interop and have other functions that return int's and those work. Can C# receive const char * pointers from C++?
Re: Returning a const char * pointer from C++ to C#?
char is the equiv. of a .net byte. a char in .net is the same as a ushort.
Assuming what is being used here is a Cstring, a string object will suffice.
Originally Posted by dktundwal
It must be IntPrt
that is not correct. strings can be marshaled to and from a char* so a string will work. you *could* use an IntPtr but why on earth would you? If you're going to be p/invoking some C function, I would think it would be more important to make the signature correct for .NET (unless what they're returning is actually a byte array).
for things like win32 a lot of times the api's deal with handles, and in this situation it is important to maintain that (most of these api's return handles, and accept handles as their parameters). For something that is returning a char* it would be better to deserialize that to a string to be used in .NET.
Re: Returning a const char * pointer from C++ to C#?
you *could* use an IntPtr but why on earth would you?
If you marshal the char* as a 'string' type, then the .NET framework will automatically call Marshal.FreeHGlobal () on the char* pointer once the .NET string has been created. If your application expects the string to *not* be freed or if it allocates/frees memory using custom functions, you cannot marshal as 'string', you must use IntPtr.
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
Re: Returning a const char * pointer from C++ to C#?
are you absolutely sure about that? I haven't read the link you posted (and it may have examples in there), but I'd find it hard to believe that the runtime would free a const char*.
Re: Returning a const char * pointer from C++ to C#?
If you marshal the char* as a 'string' type, then the .NET framework will automatically call Marshal.FreeHGlobal
Actually, no it won't.
The .NET framework has no idea what heap the memory is created on. It can either be HGLOBAL, CoAllocTaskMem or the good old 'C++' heap. Indeed since .NET dynamically loads dlls (rather than statically) it may even be using a different version of the C runtime library than .NET so may have a different C++ heap. Or it may not even be on a heap : it could be static memory e.g.
Good practice has always been with dlls - do not deallocate memory outside a dll which was allocated inside it. And do not deallocate memory inside a dll which was allocated outside it. If a dll allocated memory, the dll should destroy it and the same goes for the client code.
And in answer to the question, if the const char * is a null terminated C++ string then :
(1) Look at your dll in depends.exe. Download it (just google for depends.exe) if necessary. See the function name for test is all garbled : this is what you need to provide as the 'EntryPoint' in your DllImport call.
(2) Your C# code should look like this
Code:
[DllImport("Dll.dll", EntryPoint="---- from depends.exe ----")]
[return: MarshalAs(UnmanagedType.LPStr)]
static extern public string test(int k);
Darwen.
Last edited by darwen; June 5th, 2009 at 04:51 PM.
www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.
That will be freed and thus cause corruption. That's why you need to marshal as 'IntPtr' if you don't want automatic free'ing of char* pointers, or use a custom marshaller.
EDIT: If you want to pass a managed string to native code (C# -> C or C++) then you should read the docs i've linked to make sure you do it right.
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
Re: Returning a const char * pointer from C++ to C#?
That will be freed and thus cause corruption.
Let's try that again... no it won't. See included project.
I think you're getting mixed up between COM interop (which does indeed free BSTR and SAFEARRAY output parameters, because that's according to the COM specification) and straight PInvoke.
Darwen.
www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.
My example code demonstrates that an error is reported in debug builds in RtlFreeHeap because the default marshaler for strings attempts to deallocate the string using CoFreeTaskMem.
However this does not cause a crash : just a debug message saying that the address is wrong for RtlFreeHeap.
I have to say this seems to me to be very unexpected behaviour for the default marshaling of PInvoke : who CoAllocTaskMem's strings for returning through C++ method calls ? I certainly never have.
But I stand corrected...
My apologies
Darwen.
Last edited by darwen; June 9th, 2009 at 03:34 PM.
www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.