是否将[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上运行)。

是否将[ComImport]视为P/Invoke

不,它们不一样。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中的较低级别支持方面的结构手段时,这是没有意义的。