char * указатель из строки в C # - PullRequest
30 голосов
/ 01 ноября 2009

Возможно ли получить char* для переменной string в C #?

Мне нужно преобразовать строку пути в char* для использования некоторой встроенной функции win32 ...

Ответы [ 6 ]

42 голосов
/ 21 ноября 2010

Ну, конечно, вы могли бы сделать это:

string str = "my string";

unsafe 
{
    fixed (char* p = str)
    {               
        // do some work
    }
}

, где есть оператор (char *), связанный с строковым объектом. Тем не менее, выходной формат может быть несовместим с базовым C или другим форматом ... однако это довольно хорошее решение для разбора строки. Надеюсь, это полезно для всех, кто читает этот пост.

12 голосов
/ 01 ноября 2009

Вы можете передать StringBuilder как char*.

Посмотрите на http://pinvoke.net, чтобы увидеть, если подпись для функции еще не существует.

4 голосов
/ 02 ноября 2013

Для следующего фрагмента кода не требуется небезопасного контекста (и да, он показывает внутренние болты и биты о реализации метода string GetHashCode, что показывает его отличие с одним в Java, потому что в C # значение хеш-код не кэшируется и, как правило, показывает, что строки C # не являются окончательно неизменяемыми, как вы, возможно, учили, не можете справиться с фоном Нейманом):

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();
            }
        }
    }
}
4 голосов
/ 02 ноября 2009

Чтобы объединить 2 заданных ответа, это зависит от направления, которое вам нужно для вашего параметра.

Если функция просто нуждается во входной строке, то есть const char *, вы можете использовать аргумент типа System.String (или обычный string).

Если функция заполняет строку, т.е. char * buffer, int bufferSize, вы можете передать System.Text.StringBuilder.

В обоих случаях (авто) Marshaling сделает необходимые преобразования для вас.

4 голосов
/ 01 ноября 2009

Это зависит от того, что вы хотите сделать. Когда вы вызываете функцию Win32 через PInvoke, вы можете просто передать переменную String; Фреймворк все для вас. Если вам нужно что-то более сложное, взгляните на Marshal.StringToHGlobalAnsi и другие методы класса Marshal.

0 голосов
/ 01 ноября 2009

Вы можете получить массив byte [] из строки, используя Encoding.ASCII.GetBytes. Вероятно, это можно преобразовать в char *, используя фиксированный оператор в C #. (Это закрепляет выделенную память, не позволяя gc переместить ее - тогда вы можете сделать указатель на нее).

Так что мой ответ - да, только если вам удастся преобразовать байт * в символ *. (в C / C ++ это не будет проблемой, но я не уверен в C #)

PS> Я выложу код позже, если найду закладку к статье на эту тему. Я знаю, что у меня это есть где-то ..

...