当我制作一些P / Invoke或COM InterOP时,我经常碰到IntPtr。所以这里有几个问题:
每个人都说IntPtr是一个 struct ,那么它里面有什么?我只能想到一个32位/ 64位整数,它是指向它的地址。还有什么吗?
IntPtr在哪里?如果它是一个结构,我相信它应该在CLR 托管堆栈 中。但是,如果我在执行p / invoke时将IntPtr传递给非托管方法,是不是将其传递给 非托管堆栈 ?是否会将其复制到 非托管堆栈? 流程地址空间中有托管和非托管堆,是否存在此分离 进程'堆栈?
答案 0 :(得分:3)
IntPtr只是一个保证为指针大小的整数。因此,它通常用于在上下文中包含指针,在这些指针中,指针被认为是“不安全的”。
但是,就像指针一样,它只是一个数字。如果它包含地址,则该过程中的地址可能有效或无效。它可以是对齐的或未对齐的,它可以是当前线程的堆栈或另一个线程的堆栈或托管堆或某些非托管堆上的位置。这只是一个数字;这个数字作为指针的解释是有意义还是安全取决于你自己决定。
答案 1 :(得分:2)
是的,它只是一个指针。就是这样。
我认为你已经买进了“结构堆栈,类正在堆上”的神话。我强烈建议您阅读Eric Lippert的blog entry on this(and another one)。
答案 2 :(得分:1)
每个人都说IntPtr是一个结构,那么它的内容是什么?我只能想到一个32位/ 64位整数,它是指向它的地址。还有什么吗?
使用Reflector,您可以看到它只包含一个类型为void*
private unsafe void* m_value;
IntPtr在哪里?如果它是一个结构,我相信它应该在CLR托管堆栈中。但是,如果我在执行p / invoke时将IntPtr传递给非托管方法,是不是将它传递给非托管堆栈?它会被复制到非托管堆栈吗?进程地址空间中存在托管和非托管堆,对于进程堆栈是否也存在这种分离?
首先,结构不一定存储在堆栈中。这是一个常见的误解:它们可以存储在堆栈中,但并不意味着它总是如此(有关详细信息,请参阅this article)。
此外,没有“进程堆栈”:每个线程都有自己的堆栈。
我不知道p / invoke如何工作的所有细节,但基本上,是的,IntPtr值被复制到非托管内存。
如果您想了解有关非托管代码的互操作的更多信息,您可能会对this article感兴趣。