是否将[ComImport]视为P/Invoke
本文关键字:Invoke 视为 ComImport 是否 | 更新日期: 2023-09-27 18:20:34
是什么 平台调用(p/Invoke)?
执行p/Invoke意味着什么?它正在调用外部dll吗?例如:
[DllImport("coredll.dll", SetLastError=true)]
private static extern bool SHGetSpecialFolderPath(
int hwndOwner,
string lpszPath,
ceFolders nFolder,
bool fCreate);
p/Invoke的意思是:使用[DllImport]
属性吗?
还有什么可以被认为是P/Invoke
吗?
[ComImport]
呢?例如:
[System.Runtime.InteropServices.ComImport]
[Guid("F8383852-FCD3-11d1-A6B9-006097DF5BD4")]
public class ProgressDialog
{
}
注意:这个COM类(F8383852-FCD3-11d-A6B9-006097DF5BD4)可以在中找到
HKEY_CLASSES_ROOT'CLSID'{F8383852-FCD3-11d1-A6B9-006097DF5BD4}
(default) %SystemRoot%'system32'shell32.dll
ThreadingModel Both
我还可以用以下代码构造一个本地ADO Recordset
对象:
[System.Runtime.InteropServices.ComImport]
[Guid("00000535-0000-0010-8000-00AA006D2EA4")]
public class Recordset
{
}
Object rs= new Recordset();
这被认为是p/Invoke吗?
如果我们选择说"p/Invoke坏了",那么ComImport和DllImport一样"坏"吗?
是什么平台调用(p/Invoke)?
更新:来自MSDN:
平台调用教程
平台调用服务(PInvoke)允许托管代码调用在DLL中实现的非托管函数。
C#代码可以通过两种方式直接调用非托管代码:
- 直接调用从DLL导出的函数
- 在COM对象上调用接口方法(有关详细信息,请参阅COM Interop第1部分:C#客户端教程)
我想我可能已经回答了我自己的问题。
一年半过去了。既然没有人关注这个问题,也没有人支持它,我可以说我接受的答案是错误的。CCD_ 5是CCD_。这是一种在CLR内部运行的托管代码可以调用非托管本机(即平台)代码的机制。这几乎总是通过调用驻留在本机dll中的代码来完成的。COM dll是本机代码;它们只是遵循一个严格的结构,允许许多不同的编译器调用它们。
平台调用不好。它绕过了所有垃圾收集,并取决于平台(即,我的32位CLR进程无法加载64位dll,我为Android编写的应用程序无法在Windows上运行,我为Windows 8功能编写的应用软件无法在Windows XP上运行)。
不,它们不一样。P/Invoke(平台调用)总是涉及使用CLR功能直接调用本机DLL。"本机DLL"是指任何导出extern "C"
函数的DLL。托管DLL不允许您公开它们;这样的DLL通常是用C/C++编写的。托管代码中P/Invoke的泄露签名是DllImport
属性(或C#中的extern
函数)。读取P/Invoke页面时,不会在任何位置提及COM。
使用ComImport
的目的是创建一个自定义的互操作程序集(即手工制作的程序集,而不是由TlbImp
自动生成的PIA),并使用与p/Invoke功能完全独立的、特定于COM的固有CLR功能。
相似之处在于,这两种方法都用于与非托管代码进行互操作。对这两者的支持都被烘焙到了CLR中,尽管理论上可以使用Windows API在托管代码中完全手动地执行COM互操作,但当.NET为您提供主或自定义互操作程序集以及System.ComponentModel
中的较低级别支持方面的结构手段时,这是没有意义的。