什么是平台调用 (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:
平台调用服务 (PInvoke) 允许托管代码调用
在 DLL 中实现的非托管函数。
C# 代码可以通过两种方式直接调用非托管代码:
我想我可能已经回答了我自己的问题。
一年半过去了。既然没有人关注这个问题,也没有人收藏它,我可以说我接受的答案是错误的。 P/Invoke
是Platform 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 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).
发布评论
评论(1)
不,它们不一样。 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 aDllImport
attribute (orextern
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 byTlbImp
), 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
.