简体   繁体   English

将C ++指针数学转换为C#

[英]Converting C++ Pointer Math to C#

I'm currently working on a project that requires converting some C++ code to a C# environment. 我目前正在从事一个需要将一些C ++代码转换为C#环境的项目。 For the most part, it's actually pretty straightforward, but I'm currently converting some lower-level memory manipulation functions and running into some uncertainty as to how to proceed. 在大多数情况下,它实际上非常简单,但是我目前正在转换一些较低级别的内存操作函数,并且在如何进行方面遇到了一些不确定性。

In the C++ code, I've got a lot of instances of things like this (obviously quite simplified): 在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...
} 

I'm thinking that in C#, I've basically got to treat the "unsigned char*" as a byte array (byte[]). 我在想,在C#中,我基本上必须将“ unsigned char *”视为字节数组(byte [])。 But to perform a similar operation to the pointer arithmetic, is that essentially just increasing a "currentIndex" value for accessing the byte array? 但是要执行与指针算法类似的操作,是实质上只是增加用于访问字节数组的“ currentIndex”值吗? For something like AnotherFunc, I guess that means I'd also need to pass in a starting index, if the starting index isn't 0? 对于AnotherFunc之类的东西,我想这意味着如果起始索引不为0,我还需要传递起始索引?

Just want to confirm this is how it should be done in C#, or if there's a better way to make that sort of conversion. 只是想确认这是在C#中应该如何完成,或者是否有更好的方法来进行这种转换。 Also, I can't use the "unsafe" keyword in my current environment, so actually using pointers is not possible! 另外,我不能在当前环境中使用“不安全”关键字,因此实际上无法使用指针!

The two functions treat myMemoryBlock as if it represented an array. 这两个函数将myMemoryBlock视为代表数组。 You could replace a single myMemoryBlock parameter with a pair of myArray and myOffset , like this: 您可以用一对myArraymyOffset替换单个myMemoryBlock参数,如下所示:

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

Note: C++ type unsigned char is often used as a stand-in for "untyped block of memory" (as opposed to "a block of memory representing character data"). 注意: C ++类型的unsigned char通常用作“无类型的内存块”(而不是“代表字符数据的内存块”)的替代。 If this is the case in your situation, ie the pointer points to memory that is not necessarily character, an array of byte would be a more appropriate choice. 如果您的情况如此,即指针指向的内存不一定是字符,那么byte数组将是更合适的选择。

Just like @dasblinkenlight said, the C# (and Java) way to deal with arbitrary pointers to memory data blocks (which are usually byte or char arrays) is to add an additional offset parameter to the methods that access the data blocks. 就像@dasblinkenlight所说的那样,处理内存数据块(通常是字节或char数组)的任意指针的C#(和Java)方法是在访问数据块的方法中添加一个额外的offset参数。

It is also common to add a third length parameter. 添加第三length参数也是很常见的。 Thus the general form for a method Foo() that is passed a block of memory is: 因此,传递给内存块的方法Foo()的一般形式为:

// Operate on 'block', starting at index 'offset',
// for 'length' elements
//
int Foo(byte[] block, int offset, int length)
{ ... }

You see this all over the place in the C# library. 您可以在C#库中的各处看到它。 Another form that is common for methods that operate on two memory blocks (eg, copying one block to another, or comparing one block to another, etc.) is this: 对于在两个内存块上进行操作的方法(例如,将一个块复制到另一个或将一个块与另一个进行比较,等等)的另一种常见形式是:

// 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)
{ ... }

For methods that expect to operate on an entire memory block (array), these generally look like this: 对于希望在整个内存块(数组)上运行的方法,通常如下所示:

// Overloaded version of Foo() that
// operates on the entire array 'block'
//
int Foo(byte[] block)
{
    return Foo(block, 0, block.Length);
}

C# does away with pointers for the exact reasons of preventing pointer arithmetic (rather, the errors that pointer arithmetic is vulnerable to). C#完全出于防止指针算术(而是指针算术易受攻击的错误)的原因而放弃了指针。

Generally any C++ memory block referred to by a pointer and memory offset is indeed best translated as an array in C# (hence why even C# arrays start with [0] ).However, you should keep the array the same type as the underlying data - char[] instead of byte[] . 通常,任何由指针和内存偏移量引用的C ++内存块的确可以最好地转换为C#中的数组(因此,即使C#数组也以[0]开头)。但是,您应保持数组与基础数据的类型相同- char[]代替byte[] Because this is also a char[] , you should look at what the overall use of the function is and consider switching to a string . 由于这也是char[] ,因此您应该查看该函数的整体用途,并考虑切换到string

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM