[ComImport]被认为是P/Invoke吗?

Ian*_*oyd 6 c# com pinvoke

什么平台调用(P/Invoke)?


执行P/Invoke意味着什么?它是在调用外部DLL吗?例如:

[DllImport("coredll.dll", SetLastError=true)]
private static extern bool SHGetSpecialFolderPath(
      int hwndOwner, 
      string lpszPath,
      ceFolders nFolder,
      bool fCreate);
Run Code Online (Sandbox Code Playgroud)

这是P/Invoke的意思:使用[DllImport]属性?

还有什么可以被认为是P/Invoke

怎么样[ComImport]?例如:

[System.Runtime.InteropServices.ComImport]
[Guid("F8383852-FCD3-11d1-A6B9-006097DF5BD4")]
public class ProgressDialog
{
}
Run Code Online (Sandbox Code Playgroud)

注意:此COM类(F8383852-FCD3-11d1-A6B9-006097DF5BD4)可在以下位置找到:

HKEY_CLASSES_ROOT\CLSID\{F8383852-FCD3-11d1-A6B9-006097DF5BD4}
      (default)       %SystemRoot%\system32\shell32.dll
      ThreadingModel  Both
Run Code Online (Sandbox Code Playgroud)

我还可以ADO Recordset用代码构造一个本机对象:

[System.Runtime.InteropServices.ComImport]
[Guid("00000535-0000-0010-8000-00AA006D2EA4")]
public class Recordset
{
}

Object rs= new Recordset();
Run Code Online (Sandbox Code Playgroud)

那被认为是P/Invoke吗?

如果我们选择说"P/Invoke不好",那么ComImport与DllImport一样"糟糕"吗?

什么平台调用(P/Invoke)?


更新:来自MSDN:

平台调用教程

平台调用服务(PInvoke)允许托管代码调用DLL中实现的非托管函数.

C#代码可以通过两种方式直接调用非托管代码:

我想我可能已经回答了我自己的问题.


一年半之后.既然没有人关注这个问题,没有人对它有所帮助,我可以说我接受的答案是错误的.P/Invoke是的缩写Platform Invoke.这是一种在CLR内部运行的托管代码可以调用非托管本机(即平台)代码的机制.这几乎总是通过调用驻留在本机dll中的代码来完成的.COM dll 本机代码; 他们只是遵循严格的结构,允许许多不同的编译器调用它们.

平台调用很糟糕.它绕过所有垃圾收集,并依赖于平台(即我的32位CLR进程无法加载64位dll,我为Android编写的应用程序无法在Windows上运行,我在Windows 8上为功能编写的应用程序将无法正常工作Windows XP).

Nol*_*rin 7

不,他们不一样.P/Invoke(平台调用)总是涉及使用CLR功能直接调用本机DLL."本机DLL"表示任何展示extern "C"功能的DLL .托管DLL不允许您公开它们; 这样的DLL通常用C/C++编写.托管代码中P/Invoke的赠品签名是一个DllImport属性(或externC#中的函数).阅读P/Invoke页面并未在任何地方提及COM.

使用ComImport是为了创建自定义互操作程序集(即手工制作而不是由其自动生成的PIA TlbImp),并使用固有的CLR功能,该功能完全独立于P/Invoke功能,并且特定于COM.

相似之处在于这两种方法都用于与非托管代码进行互操作.支持两者都融入了CLR,虽然理论上可以使用Windows API在托管代码中完全手动完成COM互操作,但是当.NET为主要或自定义互操作提供结构方式时没有任何意义组件以及低级别的支持System.ComponentModel.

  • 谢谢您的回答 :-) (2认同)