pInvoke 和 COM Interop 之间有什么区别?
假设我正在访问第三方库,文档指出我可以使用 pInvoke 或创建互操作库并使用 COM。这两种技术之间有什么区别,为什么我会选择其中一种而不是另一种?
Let us say that I am accessing a third-party library, for which the documentation states that I can use pInvoke or create an interop library and use COM. What is the difference between these two techniques, and why might I choose one over the other?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
PInvoke 使用动态链接机制将外部代码引入执行过程。动态链接库 (DLL) 必须与调用应用程序具有相同的目标体系结构,因此无法进行从 64 位到 32 位的交叉调用,反之亦然。相反,DLL 被映射到调用者的地址空间并在进程中执行。
COM、DCOM、COM+ 和 ActiveX 都基于进程间通信库,但有时可以转变成简单的 DLL 加载。 COM 链接对象与 CORBA 对象相关,但并不完全相同,但是虽然 CORBA 发展了自己的对象定位器,但 COM 实现仍然松散地基于 Sun Microsystems RPC 和 XDR 库,并扩展了 COM 的面向对象功能。 COM 对象不是由 DLL 引用,而是由 GUID 引用,GUID 用于查找对象类并查询其接口。目标代码通常在单独的进程中运行,并且可能在单独的服务器上运行。
PInvoke uses the dynamic linking mechanism for bringing external code into the executing process. Dynamic linking libraries (DLLs) must have the same target architecture as the calling application, so there is no ability to make cross calls from 64-bit to 32-bit or vice versa. Instead the DLL is mapped into the caller's address space and executed in process.
COM, DCOM, COM+, and ActiveX are all based on interprocess communications libraries, but can sometimes devolve into a simple DLL load. COM linked objects are related, but not identical to CORBA objects, but while CORBA evolved its own object locator, the COM implementation is still loosely based on Sun Microsystems RPC and XDR libraries with extensions for the object oriented features of COM. COM objects are referenced not by DLL, but by a GUID which is used to look up the object class and query its interfaces. The object code usually runs in a separate process, and possibly on a separate server.
根据互操作性(C# 编程指南),
正如 Kevin Smathers 所说的在这个线程的其他地方,
(强调我的。)
根据 互操作性的性能注意事项(C++),部分 P/Invoke 与 C++ 互操作,
下面的 P/Invoke 示例:
COM 互操作示例< /a> (在使用 C# 代码的 C++ 中):
According to Interoperability (C# Programming Guide),
As Kevin Smathers has stated elsewhere in this thread,
(Emphasis mine.)
Per Performance Considerations for Interop (C++), section P/Invoke vs. C++ Interop,
P/Invoke example below:
COM interop example (in C++ that is consuming C# code):
P/Invoke 用于调用纯 C API(如大多数 Win32 API)。 COM互操作用于调用COM对象。
您可以围绕 C API 创建一个 C++ COM 包装器,然后如果 API 调用数量相对较高,则使用 COM 互操作来调用您的包装器(并且您可以使用 COM 包装器将它们封装为一两个调用)。这是因为托管本机互操作可能相对昂贵,并且最好尽量减少转换次数。虽然实际上我会说使用 C++/CLI 创建包装器对于 C# 方面可能更友好一些(查看 SlimDX ,例如,它是 COM API (DirectX) 的 C++/CLI 包装器。
话虽如此,除非您有特定的性能问题,否则我只会使用对于您尝试调用的 API 来说更自然的方法:如果它是 C API(如 Win32 API),则使用 P/Invoke。如果它是基于 COM 的,则使用 COM 互操作。
P/Invoke is used to call plain-C APIs (like most of the Win32 API). COM interop is used to call COM objects.
You might create a C++ COM wrapper around a C API and then use COM interop to call your wrapper if the number of API calls is relatively high (and you can use the COM wrapper to encapsulate them into just one or two calls). This is because managed-native interop can be relatively expensive and it's good to minimise the number of transitions. Though actually I would say using C++/CLI to create the wrapper would probably be a little more friendly for the C# side of thing (looking at SlimDX, for example, which is a C++/CLI wrapper around a COM API (DirectX)).
Having said that, unless you have a specific performance problem, I would just use whichever method is more natural for the API you're trying to call: if it's a C API (like the Win32 API is) then use P/Invoke. If it's COM-based, then use COM interop.