如何在C#中找到指向托管类的原始指针,希望它是内存中的原始大小?显然,CLR不允许这样做 – 更准确地说,严格禁止,因为托管类的非托管表示永远不应该出于稳定性和安全性原因而进行处理 – 所以我正在寻找一个黑客.我不...

如何在C#中找到指向托管类的原始指针,希望它是内存中的原始大小?显然,CLR不允许这样做 – 更准确地说,严格禁止,因为托管类的非托管表示永远不应该出于稳定性和安全性原因而进行处理 – 所以我正在寻找一个黑客.我不是在寻找序列化 – 我确实需要托管类的转储,因为它在原始内存中表示.
更准确地说,我在下面的例子中寻找类似函数getObjectPtr的东西:
IntPtr getObjectPtr(Object managedClass) {...}
void main() {
var test=new TestClass();
IntPtr* ptr_to_test=getObjectPtr(test);
Console.WriteLine(ptr_to_test.ToString());
}
提前致谢!
编辑:
我终于找到了一个自己的解决方案,当回来发布它作为答案时,对已经发布的答案很快就感到惊讶…感谢大家!这非常快,完全出乎意料.
最接近我的解决方案是@thehennyy的一个,但是我没有发布它,因为@Chino提出了更好的一个(抱歉我一开始就把它弄错了,我只是忘了再次取消引用指针).它不需要代码不安全,而且要求GC更容忍:
class Program
{
// Here is the function in case anyone needs it.
// Note, though, it does not preserve the handle while you work with
// pointer, so it is less reliable than the code in Main():
static IntPtr getPointerToObject(Object unmanagedObject)
{
GCHandle gcHandle = GCHandle.Alloc(unmanagedObject, GCHandleType.WeakTrackResurrection);
IntPtr thePointer = Marshal.ReadIntPtr(GCHandle.ToIntPtr(gcHandle));
gcHandle.Free();
return thePointer;
}
class TestClass
{
uint a = 0xDEADBEEF;
}
static void Main(string[] args)
{
byte[] cls = new byte[16];
var test = new TestClass();
GCHandle gcHandle = GCHandle.Alloc(test, GCHandleType.WeakTrackResurrection);
IntPtr thePointer = Marshal.ReadIntPtr(GCHandle.ToIntPtr(gcHandle));
Marshal.Copy(thePointer, cls, 0, 16); //Dump first 16 bytes...
Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(thePointer.ToInt32())));
Console.WriteLine(BitConverter.ToString(cls));
Console.ReadLine();
gcHandle.Free();
}
}
/* Example output (yours should be different):
40-23-CA-02
4C-38-04-01-EF-BE-AD-DE-00-00-00-80-B4-21-50-73
That field's value is "EF-BE-AD-DE", 0xDEADBEEF as it is stored in memory. Yay, we found it!
*/
霍维尔,现在我有点无能为力.根据this的文章,类中的前2个地址应该是指向SyncBlock和RTTI结构的指针,因此第一个字段的地址必须偏移2个字[32位系统中的8个字节,64位系统中的16个字节]从最开始.我的是64位;但是,正如您在输出中看到的那样,很明显第一个字段与对象地址的原始偏移量仅为4个字节,这没有任何意义.
我把它称为separate question.
也许我应该将此问作为一个单独的问题,但我的解决方案可能存在错误.
解决方法:
嘿,这就是你想要的吗?:
GCHandle gcHandle = GCHandle.Alloc(yourObject,GCHandleType.WeakTrackResurrection);
IntPtr thePointer = GCHandle.ToIntPtr(gcHandle);
本文标题为:c# – 如何获取托管类的原始内存指针?


基础教程推荐
- C#中的Linq to JSON操作详解 2023-06-08
- 实例详解C#实现http不同方法的请求 2022-12-26
- C#获取指定目录下某种格式文件集并备份到指定文件夹 2023-05-30
- C#通过标签软件Bartender的ZPL命令打印条码 2023-05-16
- C#调用摄像头实现拍照功能的示例代码 2023-03-09
- C#中 Json 序列化去掉null值的方法 2022-11-18
- C# 解析XML和反序列化的示例 2023-04-14
- Unity shader实现高斯模糊效果 2023-01-16
- Unity 如何获取鼠标停留位置下的物体 2023-04-10
- c# – USING块在网站与Windows窗体中的行为不同 2023-09-20