Kris
Kris

Reputation: 2123

char* pointer from string in C#

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

Answers (7)

hongxu
hongxu

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

Lu4
Lu4

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

Geoff
Geoff

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

Guillau pelletier
Guillau pelletier

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

Henk Holterman
Henk Holterman

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

Heinzi
Heinzi

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

kubal5003
kubal5003

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

Related Questions