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

时间:2012-01-18 14:18:28

标签: c# com pinvoke

平台调用(P / Invoke)?


执行P / Invoke意味着什么?是calling an external dll吗? e.g:

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

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

还有什么可以被视为P/Invoke吗?

[ComImport]怎么样? e.g:

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

注意:此COM类(F8383852-FCD3-11d1-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:

  

Platform Invoke Tutorial

     

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

     

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

     

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


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

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

1 个答案:

答案 0 :(得分:7)

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

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

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