将C中的指针转换为C#
我需要将一些使用指针的C转换成C 基本上,我得到了一个未匹配数据的缓冲区,需要处理它 好像它是格式化的。它通常是从文件中读取的,但可能不是 它可能来自运行不同硬件的嵌入式C应用程序 在本例中,我需要将其视为一个long数组 我只需要创建一个指向long的指针,然后转换缓冲区的地址 但在C#中,我不允许获取托管对象的地址 它不会让我把一个字节转换成一个长字节 那么如何在c语言中正确地实现这一点呢#将C中的指针转换为C#,c#,c,pointers,C#,C,Pointers,我需要将一些使用指针的C转换成C 基本上,我得到了一个未匹配数据的缓冲区,需要处理它 好像它是格式化的。它通常是从文件中读取的,但可能不是 它可能来自运行不同硬件的嵌入式C应用程序 在本例中,我需要将其视为一个long数组 我只需要创建一个指向long的指针,然后转换缓冲区的地址 但在C#中,我不允许获取托管对象的地址 它不会让我把一个字节转换成一个长字节 那么如何在c语言中正确地实现这一点呢# void测试函数(void) { 字符缓冲区[256]; PrintBufferAsLongPoin
void测试函数(void)
{
字符缓冲区[256];
PrintBufferAsLongPointer(缓冲区);
PrintBufferAsLongArray(缓冲区);
}
无效PrintBufferAsLongPointer(字符*缓冲区)
{
long*ptr=(long*)缓冲区;
对于(int count=0;count<64;count++)
{
printf(“%X”,*ptr++);
}
}
无效PrintBufferAsLongArray(字符*缓冲区)
{
对于(int-index=0;index<64;index++)
{
printf(“%X”,缓冲区[索引]);
}
}
在c#中,内存管理由.net framework在许多组件的帮助下自动完成。其中一个是垃圾收集器,它负责从未使用的对象中清除内存。另一方面,在c语言中,内存由程序员处理。程序员可以完全访问内存。他可以创建和销毁对象。他可以利用指针引用程序虚拟内存中的某些位置,等等。也就是说,我建议您避免将用c(或任何其他语言)编写的程序转换为用c#编写的程序
首先,考虑您想要实现什么,然后尝试找出如何用您选择的语言实现它
我认为你需要的是:
void static PrintBuffersContents(char[] buffer)
{
for(int index = 0; index < buffer.Length; index++)
{
Console.WriteLine(buffer[index])
}
}
void静态打印缓冲区内容(char[]缓冲区)
{
for(int index=0;index
创建一个简单的控制台应用程序,您可以测试上述内容
我想在此指出,您可以使用c#中的指针。我不认为这是不可能的。然而,这并不是c#的强项。如果你能避开它们,我建议你这样做。这种语言还有许多其他部分使它在某些方面比c语言更强大。有关c#中指针的详细说明,请查看。如果您小心(并在项目选项中启用“不安全代码”),您仍然可以在c#中使用指针:
私有静态不安全无效PrintBufferAsLongArray(字节[]缓冲区)
{
固定(字节*pBuffer=缓冲区)
{
long*longData=(long*)pBuffer;
对于(int-index=0;index<64;index++)
WriteLine({0:X}),longData[index]);
}
}
我想您要找的是位转换器.ToInt32()
下面的程序打印1、2、257、514
static void PrintBufferAsInt(byte[] buffer)
{
for(int i = 0; i < buffer.Length; i+=4)
{
var value = BitConverter.ToInt32(buffer, i);
Console.WriteLine(value);
}
}
static void Main(string[] args)
{
var buffer = new byte[] {1, 0, 0, 0, 2, 0, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0};
PrintBufferAsInt(buffer);
}
静态无效打印缓冲区(字节[]缓冲区)
{
对于(int i=0;i
你为什么选择这样做?@David:因为这是一个简单、直接的翻译。显然,有更多的.NET-y方法可以使用托管阵列等来实现这一点,但我们在这个问题上没有足够的信息来了解是否可以将整个应用程序设计更改为使用语义对象模型(这也需要反序列化和重新序列化)DavidHeffernan优化的代码中,我唯一使用过的C#指针是用于图像分析,而不是字节片。把时间从5秒降到了几秒。一个C++确实可以做得比C语言更好的是扫描阵列。FWIW,应该是代码> int <代码>而不是<代码>长< /Cord>。我认为把C函数编译成一个DLL更容易,并把它们链接到C语言的简短答案,你在C语言中不做那种事情。虽然可以,但在C#中几乎从不使用指针。NET及其托管语言被明确设计为防止无法验证的代码,而指针算法和类型转换则与此相反。如果您真的必须处理内存地址和内存布局等问题,请查看unsafe
代码、System.Runtime.InteropServices.Marshal
静态类、StructLayout
等。但是要知道,这不会产生惯用的C代码。改用类型化数组。或者,如果你必须做很多低级的事情,那么在C++中和C.保持“<代码>长< /Cord< >没有相同的长度。您可能想在C#中使用int
。您可以获取一个字节数组(byte[]
),并使用BitConverter.ToUInt32()将每4个字节转换为一个int。多亏了这一点,我才了解了大部分内容,它对简单类型的数组还是有帮助的。struct的数组可能需要更多的思考。
private static unsafe void PrintBufferAsLongArray(byte[] buffer)
{
fixed (byte* pBuffer = buffer)
{
long* longData = (long*)pBuffer;
for (int index = 0; index < 64; index++)
Console.WriteLine(" {0:X}", longData[index]);
}
}
static void PrintBufferAsInt(byte[] buffer)
{
for(int i = 0; i < buffer.Length; i+=4)
{
var value = BitConverter.ToInt32(buffer, i);
Console.WriteLine(value);
}
}
static void Main(string[] args)
{
var buffer = new byte[] {1, 0, 0, 0, 2, 0, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0};
PrintBufferAsInt(buffer);
}