CPP to Rust need help

#1

Hi, I have the CPP code, there were difficulties in the translation, could not tell my mistakes pls.
CPP code
Rust code

BIG THX

#2

What’s not working in particular - and what’s your goal with this rust code?

It seems to me like the functions mem_set and copy could be replaced by equivalent safe code without needing the pointer manipulations, which makes me wonder what your goal here is. (mem_set could just use array indexing, copy could use [T]::copy_from_slice - playground).

In mem_put, you’re comparing a *mut u8 to a &mut [u8]. You’ll want to convert the &mut [u8] to a *mut u8 first so they’re the same type. Then you try to pass *mut u8 as a &[u8], which is also the wrong type.

In Rust &mut [u8] and *mut [u8] are two very different types with very different guarantees. Mutable references are guaranteed to point to initialized memory, and if a mutable reference exists it’s guaranteed that no other mutable or immutable references exist pointing to the same area. Pointers on the other hand have no such guarantees to uphold.

In addition to this, there’s one other difference: *mut u8 cannot be converted to *mut [u8] (or &[u8]). This is because *mut u8 is a single pointer, but *mut [u8] is a pointer alongside a length. You can use slice::from_raw_parts to create a slice using a pointer like this and supply a length like 1, but that’s still assuming a lot about what the caller is giving you.

You can fix mem_put by casting using x as Type to convert between *mut and &mut types, and you can fix it to take in a *mut [u8], but even then I would hesitate to call it correct. The C++ version of mem_put takes in a single pointer, not an array, and I believe that’s what allows it to get away with just checking !=. With your version taking an array, you will also want to check whether the lengths overlap at all! Silly example: As written, ptr could be pointing to memory address 5, and value could be pointing to address 4 with length = 4. Then the addresses wouldn’t be equal, but they’d still overlap and you would be invoking Undefined Behavior when converting ptr to a &[u8] to pass into copy.


In any case, I would definitely ask again what you want out of this code. It seems like you’re using unsafe just for the sake of copying the C++ code, which really won’t let you take advantage of Rust’s safety.

3 Likes
#3

For example in CPP I use it like this:
CUtils::memSet((void*)MAIN_ADDRESS, 0xC3, 1);
CUtils::memPut(MAIN_ADDRESS, 0x0);
CUtils::memCpy((void*)MAIN_ADDRESS, “\xC1\x90\x90\x90\x90”, 5);

#define MAIN_ADDRESS 0x296E629C