简体   繁体   中英

Converting C++ Pointer Math to C#

I'm currently working on a project that requires converting some C++ code to a C# environment. 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):

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[]). But to perform a similar operation to the pointer arithmetic, is that essentially just increasing a "currentIndex" value for accessing the byte array? 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?

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. 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. You could replace a single myMemoryBlock parameter with a pair of myArray and myOffset , like this:

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

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.

It is also common to add a third length parameter. Thus the general form for a method Foo() that is passed a block of memory is:

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

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[] . Because this is also a char[] , you should look at what the overall use of the function is and consider switching to a string .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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