[ComImport] 是否被视为 P/Invoke?

发布于 2024-12-27 18:56:02 字数 2153 浏览 1 评论 0 原文

什么是平台调用 (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-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();

Is考虑过 P/Invoke 吗?

如果我们选择说“P/Invoke 不好”,ComImport 是否和 DllImport 一样“不好”?

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


更新:来自 MSDN:

平台调用教程< /h2>

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

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

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


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

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

What is Platform Invoke (P/Invoke)?


What does it mean to be performing a P/Invoke? Is it calling an external dll? e.g.:

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

Is that what P/Invoke means: to use the [DllImport] attribute?

Is there anything else that can be considered a P/Invoke?

What about [ComImport]? e.g.:

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

Note: This COM class (F8383852-FCD3-11d1-A6B9-006097DF5BD4) can be found in

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

i could also construct a native ADO Recordset object with the code:

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

Object rs= new Recordset();

Is that considered P/Invoke?

If we choose to say "P/Invoke is bad", is ComImport as "bad" as DllImport?

What is Platform Invoke (P/Invoke)?


Update: From MSDN:

Platform Invoke Tutorial

Platform Invocation Services (PInvoke) allows managed code to call
unmanaged functions that are implemented in a DLL.

There are two ways that C# code can directly call unmanaged code:

i think i may have answered my own question.


It's a year and a half later. Now that nobody is paying attention to the question, and nobody has it favorited, i can say that the answer i accepted is wrong. P/Invoke is short for Platform Invoke. It is a mechanism where managed code operating inside the CLR can call unmanaged native (i.e. platform) code. This is nearly always done by calling code that resides in a native dll. COM dlls are native code; they just follow a strict structure to allow many different compilers to call them.

And Platform Invoke is bad. It bypasses all garbage collection, and depends on the platform (i.e. my 32-bit CLR process cannot load a 64-bit dll, my application written for Android cannot work on Windows, my application written for functionality on Windows 8 won't work on Windows XP).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一江春梦 2025-01-03 18:56:02

不,它们不一样。 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 的固有 CLR 功能功能,并且特定于 COM。

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

No, they are not the same. P/Invoke (platform invoke) always involves calling native DLLs directly using the CLR functionality. "Native DLLs" means any DLL that expoes extern "C" functions. Managed DLLs don't let you expose them; such a DLL is typically written in C/C++. The give-away signature of P/Invoke in managed code is a DllImport attribute (or extern function in C#). Reading the P/Invoke page gives no mention of COM anywhere.

Using ComImport is for the purpose of creating a custom interop assembly (i.e. something hand-crafted rather than a PIA automatically generated by TlbImp), and uses inherent CLR functionality that is quite independent from the P/Invoke functionality, and specific to COM.

The similarities lie in that both these methods are used for interoperating with unmanaged code. Support for both is baked into the CLR, and although in theory one could use the Windows API to do COM interop completely manually in managed code, it makes no sense when .NET provides a structure means for you, in terms of primary or custom interop assemblies as well as lower-level support in System.ComponentModel.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文