C# 中来自字符串的 char* 指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1658269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 19:44:54  来源:igfitidea点击:

char* pointer from string in C#

c#pointerschar

提问by Kris

Is it possible to get a char*for a stringvariable in C#?

是否有可能在 C# 中获得一个char*forstring变量?

I need to convert a path string to a char*for using some native win32 function ...

我需要将路径字符串转换为 achar*以使用一些本机 win32 函数...

采纳答案by Geoff

You can pass a StringBuilderas a char*.

您可以将 aStringBuilder作为char*.

Have a look at http://pinvoke.netto see if the signature for the function is not already there.

查看http://pinvoke.net以查看该函数的签名是否已经存在。

回答by kubal5003

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).

您可以使用 Encoding.ASCII.GetBytes 从字符串中获取 byte[] 数组。这可能可以使用 C# 中的固定语句转换为 char*。(这固定分配的内存,不允许 gc 移动它 - 然后你可以创建一个指向它的指针)。

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#)

所以我的答案是肯定的,前提是你设法将 byte* 转换为 char*。(在 C/C++ 中,这不是问题,但我对 C# 不太确定)

PS> I'll post some code later if I find a bookmark to an article on this. I know I have it somewhere..

PS> 如果我找到有关此文章的书签,我稍后会发布一些代码。我知道我在某个地方有它..

回答by Heinzi

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.StringToHGlobalAnsiand other methods of the Marshalclass.

这取决于你想做什么。当您通过 PInvoke 调用 Win32 函数时,您应该能够只传递 String 变量;框架为您整理一切。如果您需要更复杂的东西,请查看Marshal.StringToHGlobalAnsiMarshal该类的其他方法。

回答by Henk Holterman

To combine 2 anwers already given, it depends on the direction you need for your parameter.

要组合已经给出的 2 个 anwers,这取决于您的参数所需的方向。

If the function just needs an input string, ie const char *, you can use an argument of type System.String(or plain string).

如果函数只需要输入字符串,即const char *,您可以使用类型System.String(或普通string)的参数。

If the function fills a string, ie char * buffer, int bufferSize, you can pass a System.Text.StringBuilder.

如果函数填充一个字符串,即 char * buffer, int bufferSize,您可以传递一个System.Text.StringBuilder.

In both cases the (auto-)Marshaling will do the necessary conversions for you.

在这两种情况下,(自动)编组都会为您进行必要的转换。

回答by Guillau pelletier

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.

其中有一个运算符 (char*) 绑定到字符串对象。但是,输出格式可能与底层 C 或其他格式不兼容……然而,这是解析字符串的一个很好的解决方案。希望对看到这篇文章的人有所帮助。

回答by Lu4

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 GetHashCodemethod 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):

下面的一段代码不需要不安全的上下文(是的,它显示了关于string'sGetHashCode方法实现的内部螺栓和位,表明它与 Java 中的不同,因为在 C# 中,哈希码的值没有被缓存,通常它显示C# 字符串并不是像你可能已经被教导的那样最终是不可变的,无法处理 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();
            }
        }
    }
}