5

Can the following snippet be converted to C#.NET?

template <class cData>
cData Read(DWORD dwAddress)
{
    cData cRead; //Generic Variable To Store Data
    ReadProcessMemory(hProcess, (LPVOID)dwAddress, &cRead, sizeof(cData), NULL); //Win API - Reads Data At Specified Location 
    return cRead; //Returns Value At Specified dwAddress
}

This is really helpful when you want to read data from memory in C++ because it's generic: you can use Read<"int">(0x00)" or Read<"vector">(0x00) and have it all in one function.

In C#.NET, it's not working for me because, to read memory, you need the DLLImport ReadProcessMemory which has pre-defined parameters, which are not generic of course.

Pang
  • 9,564
  • 146
  • 81
  • 122
mirc00
  • 63
  • 3
  • Perhaps you can use the strategy suggested here: http://stackoverflow.com/a/6336196/3150802. But admittedly I'm not sure how to package that in a neat one-shot generic function. Perhaps force the classes used to read to implement some kind of serializable interface. – Peter - Reinstate Monica Nov 13 '15 at 10:59
  • For value types (structs which only contain unmanaged data) you can probably just use the memory address as pointer to the struct and return a copy of that instance, completely generically, with a `where T: struct` constraint on the type argument. – Peter - Reinstate Monica Nov 13 '15 at 11:09
  • In your new non-"answer" below you sudenly say that you want a vector returned. Can you clarify (in this original post, of course)? The question is interesting, but I do not see why you would want to produce a vector if there is an int at a given address. – Peter - Reinstate Monica Nov 13 '15 at 13:24

1 Answers1

2

Wouldn't something like this work?

using System.Runtime.InteropServices;

public static T Read<T>(IntPtr ptr) where T : struct
{
   return (T)Marshal.PtrToStructure(ptr, typeof(T));
}

This would only work with structures, you'd need to consider marshalling strings like a special non generic case if you need it.

A simple check to see if it works:

var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
var three = 3;
Marshal.StructureToPtr(three, ptr, true);
var data = Read<int>(ptr);
Debug.Assert(data == three); //true
InBetween
  • 32,319
  • 3
  • 50
  • 90