![]() |
1
10
一开始很容易。pinvoke封送拆收器首先调用LoadLibrary并传递指定的DLL名称DllImportAttribute.Value属性。在您的例子中,已经加载了user32.dll,因为它是由.NET引导程序加载的,它的引用计数只是增加了。但通常Windows加载程序会将DLL映射到进程的地址空间中,以便可以调用导出的函数。
现在我需要挥挥手了,因为这很棘手。封送拆收器构造堆栈帧,设置需要传递给导出函数的参数。这需要低级别的代码,小心地从窥探的眼睛中排除。从表面上看,它执行封送处理类支持的转换类型,以便在托管类型和非托管类型之间进行转换。这里,DllImportAttribute.CallingConvention属性很重要,因为它决定了需要将哪个参数值放在哪里,以便被调用的函数能够正确地读取它。 接下来,它将设置SEH异常处理程序,以便捕获被调用代码引发的硬件异常并将其转换为托管异常。生成更常见的一个,AccessViolationException。还有其他人。 接下来,它在堆栈上推送一个特殊的cookie,以指示非托管代码即将开始使用堆栈。这可以防止垃圾收集器误入非托管堆栈帧,并将在其中找到的指针解释为托管对象引用。您可以在调试器的调用堆栈中看到这个cookie,[托管到本机转换]。 接下来,只是对GetProcAddress()函数地址的间接调用。使非托管代码运行。
|
![]() |
2
8
非托管内存分配来自进程堆。您负责分配/解除分配内存,因为GC不知道这些对象,所以不会收集垃圾。 |
![]() |
3
1
正如一篇学术文章在这里所发布的信息一样:
|
![]() |
4
0
你的问题有一部分是由迈克尔回答的。我回答另一部分。
|
![]() |
A B · C#Excel自动调整列避免长文本时出错 5 月前 |
![]() |
Megrez7 · C#ToArray转换合并为一行,导致数组元素更改 5 月前 |
![]() |
Aycon · 在工厂方法中释放部分创建的对象的正确方法是什么? 5 月前 |
|
Sei · Avalonia/WPF将路由器传递到控制模板 6 月前 |