将 C++ 指针数学转换为 C#
Converting C++ Pointer Math to C#
我目前正在从事一个需要将一些 C++ 代码转换为 C# 环境的项目。在大多数情况下,它实际上非常简单,但我目前正在将一些较低级别的内存操作函数和 运行 转换为一些关于如何进行的不确定性。
在 C++ 代码中,我有很多这样的实例(显然非常简单):
void SomeFunc(unsigned char* myMemoryBlock)
{
AnotherFunc(myMemoryBlock);
AnotherFunc(myMemoryBlock + memoryOffset);
}
void AnotherFunc(unsigned char* data)
{
// Also simplified - basically, modifying the
// byte pointed to by data and then increasing to the next item.
*data = 2;
data++;
*data = 5;
data++;
// And so on...
}
我认为在 C# 中,我基本上必须将 "unsigned char*" 视为字节数组 (byte[])。但是要执行与指针运算类似的操作,本质上只是增加一个 "currentIndex" 值来访问字节数组吗?对于像 AnotherFunc 这样的东西,我想这意味着我还需要传入一个起始索引,如果起始索引不是 0?
只是想确认这是在 C# 中应该如何完成的,或者是否有更好的方法来进行这种转换。另外,在我现在的环境下不能使用"unsafe"关键字,所以实际使用指针是不可能的!
C# 取消指针的确切原因是防止指针运算(更确切地说,指针运算容易出错)。
一般来说,任何由指针和内存偏移量引用的 C++ 内存块在 C# 中确实最好转换为数组(因此即使 C# 数组也以 [0]
开头)。但是,您应该将数组保留为与基础数据相同的类型 -char[]
而不是 byte[]
。因为这也是一个char[]
,你应该看看这个函数的整体用途是什么,考虑换成一个string
.
这两个函数将 myMemoryBlock
视为一个数组。您可以将单个 myMemoryBlock
参数替换为一对 myArray
和 myOffset
,如下所示:
void SomeFunc(char[] myArray)
{
AnotherFunc(myArray, 0);
AnotherFunc(myArray, memoryOffset);
}
void AnotherFunc(char[] data, int offset)
{
// Also simplified - basically, modifying the
// byte pointed to by data and then increasing to the next item.
data[offset++] = 2;
data[offset++] = 5;
// And so on...
}
注意: C++ 类型 unsigned char
通常用作 "untyped block of memory" 的替代(相对于 "a block of memory representing character data")。如果您的情况是这种情况,即指针指向不一定是字符的内存,则 byte
数组将是更合适的选择。
正如@dasblinkenlight所说,C#(和Java)处理指向内存数据块(通常是字节或字符数组)的任意指针的方法是添加一个额外的offset
访问数据块的方法的参数。
添加第三个 length
参数也很常见。因此,传递一块内存的方法 Foo()
的一般形式是:
// Operate on 'block', starting at index 'offset',
// for 'length' elements
//
int Foo(byte[] block, int offset, int length)
{ ... }
您在 C# 库中随处可见。对于在两个内存块上操作的方法(例如,将一个块复制到另一个块,或将一个块与另一个块进行比较等)的另一种常见形式是:
// Operate on blocks 'src' starting at index 'srcOff',
// and on block 'dst' starting at 'dstOff',
// for a total of 'length' elements
//
int Bar(byte[] src, int srcOff, byte[] dst, int dstOff, int length)
{ ... }
对于期望对整个内存块(数组)进行操作的方法,这些方法通常如下所示:
// Overloaded version of Foo() that
// operates on the entire array 'block'
//
int Foo(byte[] block)
{
return Foo(block, 0, block.Length);
}
我目前正在从事一个需要将一些 C++ 代码转换为 C# 环境的项目。在大多数情况下,它实际上非常简单,但我目前正在将一些较低级别的内存操作函数和 运行 转换为一些关于如何进行的不确定性。
在 C++ 代码中,我有很多这样的实例(显然非常简单):
void SomeFunc(unsigned char* myMemoryBlock)
{
AnotherFunc(myMemoryBlock);
AnotherFunc(myMemoryBlock + memoryOffset);
}
void AnotherFunc(unsigned char* data)
{
// Also simplified - basically, modifying the
// byte pointed to by data and then increasing to the next item.
*data = 2;
data++;
*data = 5;
data++;
// And so on...
}
我认为在 C# 中,我基本上必须将 "unsigned char*" 视为字节数组 (byte[])。但是要执行与指针运算类似的操作,本质上只是增加一个 "currentIndex" 值来访问字节数组吗?对于像 AnotherFunc 这样的东西,我想这意味着我还需要传入一个起始索引,如果起始索引不是 0?
只是想确认这是在 C# 中应该如何完成的,或者是否有更好的方法来进行这种转换。另外,在我现在的环境下不能使用"unsafe"关键字,所以实际使用指针是不可能的!
C# 取消指针的确切原因是防止指针运算(更确切地说,指针运算容易出错)。
一般来说,任何由指针和内存偏移量引用的 C++ 内存块在 C# 中确实最好转换为数组(因此即使 C# 数组也以 [0]
开头)。但是,您应该将数组保留为与基础数据相同的类型 -char[]
而不是 byte[]
。因为这也是一个char[]
,你应该看看这个函数的整体用途是什么,考虑换成一个string
.
这两个函数将 myMemoryBlock
视为一个数组。您可以将单个 myMemoryBlock
参数替换为一对 myArray
和 myOffset
,如下所示:
void SomeFunc(char[] myArray)
{
AnotherFunc(myArray, 0);
AnotherFunc(myArray, memoryOffset);
}
void AnotherFunc(char[] data, int offset)
{
// Also simplified - basically, modifying the
// byte pointed to by data and then increasing to the next item.
data[offset++] = 2;
data[offset++] = 5;
// And so on...
}
注意: C++ 类型 unsigned char
通常用作 "untyped block of memory" 的替代(相对于 "a block of memory representing character data")。如果您的情况是这种情况,即指针指向不一定是字符的内存,则 byte
数组将是更合适的选择。
正如@dasblinkenlight所说,C#(和Java)处理指向内存数据块(通常是字节或字符数组)的任意指针的方法是添加一个额外的offset
访问数据块的方法的参数。
添加第三个 length
参数也很常见。因此,传递一块内存的方法 Foo()
的一般形式是:
// Operate on 'block', starting at index 'offset',
// for 'length' elements
//
int Foo(byte[] block, int offset, int length)
{ ... }
您在 C# 库中随处可见。对于在两个内存块上操作的方法(例如,将一个块复制到另一个块,或将一个块与另一个块进行比较等)的另一种常见形式是:
// Operate on blocks 'src' starting at index 'srcOff',
// and on block 'dst' starting at 'dstOff',
// for a total of 'length' elements
//
int Bar(byte[] src, int srcOff, byte[] dst, int dstOff, int length)
{ ... }
对于期望对整个内存块(数组)进行操作的方法,这些方法通常如下所示:
// Overloaded version of Foo() that
// operates on the entire array 'block'
//
int Foo(byte[] block)
{
return Foo(block, 0, block.Length);
}