Reputation: 2123
Is it possible to get a char*
for a string
variable in C#?
I need to convert a path string to a char*
for using some native win32 function ...
Upvotes: 41
Views: 97612
Reputation: 772
Like some other posts pointed out, fixed (char* p = str)
is not really compatible with native format and StringBuilder
does not really work either. This is what worked for me:
fixed (byte* p = Encoding.ASCII.GetBytes(str))
{
native_call((char*)p);
}
Upvotes: 0
Reputation: 15032
No unsafe context is required for the following piece of code (and yeah it shows the internal bolts and bits about the implementation of string
's GetHashCode
method shows it's difference with one in Java because in C# the value of hashcode isn't cached and generally it shows that C# strings are not ultimately immutable like you might have been taught, can't deal with Fon Neiman):
using System;
using System.Runtime.InteropServices;
namespace Guess
{
class Program
{
static void Main(string[] args)
{
const string str = "ABC";
Console.WriteLine(str);
Console.WriteLine(str.GetHashCode());
var handle = GCHandle.Alloc(str, GCHandleType.Pinned);
try
{
Marshal.WriteInt16(handle.AddrOfPinnedObject(), 4, 'Z');
Console.WriteLine(str);
Console.WriteLine(str.GetHashCode());
}
finally
{
handle.Free();
}
}
}
}
Upvotes: 10
Reputation: 4746
You can pass a StringBuilder
as a char*
.
Have a look at http://pinvoke.net to see if the signature for the function is not already there.
Upvotes: 13
Reputation: 631
Well you could certainly do this:
string str = "my string";
unsafe
{
fixed (char* p = str)
{
// do some work
}
}
where there is an operator (char*) bound to the string object. However, the output format may not be compatible with the underlying C or other format... this is however quite a good solution to parse the string. Hope it's helpful for anybody who reads this post.
Upvotes: 63
Reputation: 273691
To combine 2 anwers already given, it depends on the direction you need for your parameter.
If the function just needs an input string, ie const char *
, you can use an argument of type System.String
(or plain string
).
If the function fills a string, ie char * buffer, int bufferSize
, you can pass a System.Text.StringBuilder
.
In both cases the (auto-)Marshaling will do the necessary conversions for you.
Upvotes: 4
Reputation: 172448
That depends on what you want to do. When you call a Win32 function via PInvoke, you should be able to just pass the String variable; the framework marshals everything for you. If you need something more complicated, have a look at Marshal.StringToHGlobalAnsi and other methods of the Marshal
class.
Upvotes: 5
Reputation: 7254
You can get byte[] array from string using Encoding.ASCII.GetBytes. This is probably convertible to char* using fixed statement in C#. (This pins the allocated memory, not allowing gc to move it - then you can make a pointer to it).
So my answer is yes only if you manage to convert byte* to char*. (in C/C++ this wouldn't be a problem, but I'm not that sure about C#)
PS> I'll post some code later if I find a bookmark to an article on this. I know I have it somewhere..
Upvotes: 1