平台调用P/INVOKE
我们在做项目时,常常要用到别的公司开发的硬件产品, 而有关对硬件产品的控制的
DEMO 又常常是用VC6.0编写的,我们如何将他们编写的DLL应用到我们现在的.net环境中些,
微软为我们提供了”平台调用服务 (P/Invoke)”来方便的使用它们.
通过平台调用服务,托管代码可以调用本机(非 ActiveX) DLL 中实现的非托管函数。
P/Invoke 语义方面的用法与在 .NET Framework 完整版中相同, 但 .NET Framework 精简
版对于非托管和托管代码之间封送的对象和类型只提供有限的支持。
P/Invoke 位于 System.Runtime.InteropService 命名空间中。在应用程序代码中,应
该声明要调用的非托管函数。此操作可以通过 DllImport 属性执行。说明包括模块名称(
特定的 DLL 文件名)、入口点名称(要调用的非托管函数的名称)、调用约定和
SetLastError 标志。调用约定描述了将参数传递给非托管方法的方式。在 .NET Framework
精简版中,所支持的唯一调用约定是 WinAPI 约定,此约定与 C++ 中的 __cdecl 约定对应。
默认情况下,C# 将 SetLastError 标志设置为 false。 将其设置为 true 允许您调用
Marshal.GetLastWin32Error,以检索引发的上一个非托管错误。
例如,要调用非托管 DLL(即 coredll.dll)中的 FindWindow 函数,应在项目中
包含以下代码:
[DllImport("coredll.dll","FindWindow",SetLastError= true)]
public extern IntPtr FindWindow( string ClassName, string WindowName);
我们在调用它们时更多是要注意非托管数据类型与托管数据类型之间的对应关系,是传
值还是传地址。 如果处理不好 , 即便只有一个错误,你的程序就有可能无法运行。 好在
vs.net2005对你转换的错误会有一些提示,不过你还是要小心为好。
如unsigned int BaseAddr 对应转换成
[MarshalAs(UnmanagedType.U4)] Uint32 BaseAddr;
你不可将其转换成:
[MarshalAs(UnmanagedType.U1)] byte cx;
虽然 Byte 为 8位无符号整数.
详细的说明请参看MSDN。本文只是学习笔记,仅供参考。希望也能给大家带来方
便。
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
LayoutKind 枚举: 控制当导出到非托管代码时对象的布局。
成员:
成员名称 |
说明 |
Auto |
运行库自动为非托管内存中的对象的成员选择适当的布局。使用此枚举成员定义的对象不能在托管代码的外部公开。尝试这样做将引发异常。 |
Explicit |
对象的各个成员在非托管内存中的精确位置被显式控制。每个成员必须使用 FieldOffsetAttribute 指示该字段在类型中的位置。 |
Sequential |
对象的成员按照它们在被导出到非托管内存时出现的顺序依次布局。这些成员根据在 StructLayoutAttribute.Pack中指定的封装进行布局,并且可以是不连续的。 |
备注
此枚举与 StructLayoutAttribute 一起使用。默认情况下,公共语言运行库将使用 Auto布局值。为减少与 Auto 值关联的布局相关问题,C#、Visual Basic 和 C++ 编译器为值类型指定了 Sequential 布局。
示例:参数中有回调函数的WINAPI 函数在托管环境中的调用
(其中createThread (…) 函数中第三个参数就需要调用自定义的WINAPI 函数)
//非托管函数的托管调用声明
[StructLayout(LayoutKind.Sequential)] //在本例中没有用到它.
public struct SECURITY_ATTRIBUTES
{
uint nLength;
IntPtr lpSecurityDescriptor;
UInt32 bInheritHandle;
} ;
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr CreateEvent(IntPtr lpEventAttributes, Boolean bManualReset,Boolean bInitialState, [MarshalAs(UnmanagedType.LPStr)] String lpName);
[DllImport("kernel32")]
public static extern IntPtr CreateThread(
IntPtr lpThreadAttributes,
uint dwStackSize,
ThreadProc lpStartAddress, // ThreadProc as friendly delegate
IntPtr lpParameter,
uint dwCreationFlags,
out uint dwThreadId);
//函数原型可参看msdn
定义:自定义WINAPI函数在托管环境下的声明
//stdcall //c++中的 自定义的WINAPI 函数: DWORD WINAPI Fun1Proc(LPVOID lpParameter)
static int Fun1Proc(IntPtr lpParameter)
{
MessageBox.Show ("thread is running");
return 0;
}
// Thread proc, to be used with Create*Thread
public delegate int ThreadProc(IntPtr param);
//使用:
using DWORD =System.Int32 ;
using WORD =System.Int16 ;
using HANDLE = System.IntPtr;
using HWND = System.IntPtr;
using HDC = System.IntPtr;
using PVOID = System.IntPtr;
using LPVOID = System.IntPtr;
HANDLE hThread=IntPtr.Zero;
uint x = 0;
ThreadProc proc = new ThreadProc(Fun1Proc);
hThread = CreateThread(
IntPtr.Zero,
0,
proc, hEvent,
0, // flags
out x);
WaitForSingleObject (hThread,unchecked((uint)-1));
CloseHandle (hThread);
MessageBox.Show ( "main thread is running" );
//CreateEvent 函数原型
//CreateEvent, Win API, as implemented in kernel32.dll:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName
);
//WINAPI 函数在托管环境下的声明示例
[DllImport("kernel32.dll, SetLastError=true ")]
static extern IntPtr CreateEvent(IntPtr lpEventAttributes,
bool bManualReset, bool bInitialState,
[MarshalAs(UnmanagedType.LPStr) string lpName);
VB.NET
Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA"(_
ByVal dwFlags As Integer, ByRef lpSource As Object, _
ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, _
ByVal lpBuffer As String, ByVal nSize As Integer, _
ByRef Arguments As Integer) As Integer
C# definition
[DllImport("kernel32.dll", SetLastError=true)]
static extern int FormatMessageA ( int dwFlags, ref object lpSource,
int dwMessageId, int dwLanguageId, string lpBuffer,
int nSize, ref int Arguments)
Managed C++. NET
[DllImport("KERNEL32.DLL",EntryPoint="MoveFileW",
SetLastError=true,CharSet=CharSet::Unicode,ExactSpelling=true,
CallingConvention=CallingConvention::StdCall)]
static bool MoveFile( String^ src, String^ dst );
更为详细的介绍请看:
WIN API查看器
http://www.codeproject.com/csharp/APIBrowser.asp
<<A Closer Look at Platform Invoke>>
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconacloserlookatplatforminvoke.asp
<<Marshaling Data with Platform Invoke>>
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconmarshalingdatawithplatforminvoke.asp
http://www.pinvoke.net/
http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=75122f62-5459-4364-b9ba-7b5e6a4754fe
附录1:Windows Data Type 与 .NET Data Type 的对应关系
Windows Data Type |
.NET Data Type |
BOOL, BOOLEAN |
Boolean or Int32 |
BSTR |
String |
BYTE |
Byte |
CHAR |
Char |
DOUBLE |
Double |
DWORD |
Int32 or UInt32 |
FLOAT |
Single |
HANDLE (and all other handle types, such as HFONT and HMENU) |
IntPtr, UintPtr orHandleRef |
HRESULT |
Int32 or UInt32 |
INT |
Int32 |
LANGID |
Int16 or UInt16 |
LCID |
Int32 or UInt32 |
LONG |
Int32 |
LPARAM |
IntPtr, UintPtr orObject |
LPCSTR |
String |
LPCTSTR |
String |
LPCWSTR |
String |
LPSTR |
String orStringBuilder* |
LPTSTR |
String orStringBuilder |
LPWSTR |
String orStringBuilder |
LPVOID |
IntPtr, UintPtr orObject |
LRESULT |
IntPtr |
SAFEARRAY |
.NET array type |
SHORT |
Int16 |
TCHAR |
Char |
UCHAR |
SByte |
UINT |
Int32 or UInt32 |
ULONG |
Int32 or UInt32 |
VARIANT |
Object |
VARIANT_BOOL |
Boolean |
WCHAR |
Char |
WORD |
Int16 or UInt16 |
WPARAM |
IntPtr, UintPtr orObject |
附录2: 托管数据类型与非托管数据类型对比表
Unmanaged type in Wtypes.h |
Unmanaged C language type |
Managed class name |
Description |
HANDLE |
void* |
System.IntPtr |
32 bits |
BYTE |
unsigned char |
System.Byte |
8 bits |
SHORT |
short |
System.Int16 |
16 bits |
WORD |
unsigned short |
System.UInt16 |
16 bits |
INT |
int |
System.Int32 |
32 bits |
UINT |
unsigned int |
System.UInt32 |
32 bits |
LONG |
long |
System.Int32 |
32 bits |
BOOL |
long |
System.Int32 |
32 bits |
DWORD |
unsigned long |
System.UInt32 |
32 bits |
ULONG |
unsigned long |
System.UInt32 |
32 bits |
CHAR |
char |
System.Char |
Decorate with ANSI. |
LPSTR |
char* |
System.String orSystem.StringBuilder |
Decorate with ANSI. |
LPCSTR |
Const char* |
System.String orSystem.StringBuilder |
Decorate with ANSI. |
LPWSTR |
wchar_t* |
System.String orSystem.StringBuilder |
Decorate with Unicode. |
LPCWSTR |
Const wchar_t* |
System.String orSystem.StringBuilder |
Decorate with Unicode. |
FLOAT |
Float |
System.Single |
32 bits |
DOUBLE |
Double |
System.Double |
64 bits |
附录3: C/C++与C#的数据类型对应关系
C/C++ |
C# |
HANDLE, LPDWORD, LPVOID, void* |
IntPtr |
LPCTSTR, LPCTSTR, LPSTR, char*, const char*,Wchar_t*, LPWSTR |
String [in], StringBuilder [in, out] |
DWORD, unsigned long, Ulong |
UInt32,[MarshalAs(UnmanagedType.U4)] |
bool |
bool |
LP<struct> |
[In] ref <struct> |
SIZE_T |
uint |
LPDWORD |
out uint |
LPTSTR |
[Out] StringBuilder |
PULARGE_INTEGER |
out ulong |
WORD |
uInt16 |
Byte, unsigned char |
byte |
Short |
Int16 |
Long, int |
Int32 |
float |
single |
double |
double |
NULL pointer |
IntPtr.Zero |
Uint |
Uint32 |
当结构体中是一个数据类型指针时,采用.net对应的数据类型替换.
当结构体中的变量是另一个结构体的指针时,采用IntPtr类型来操作.
FlashWindow
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
平台调用P/INVOKE相关推荐
- C#中的平台调用(P/Invoke)
C#中的P/Invoke 在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中 ...
- 在 C# 中通过 P/Invoke 调用Win32 DLL
,.NET Framework 1.0 或 1.1 版类库中存在任何 Windows 所没有的功能限制都不足为怪.毕竟,32 位的 Windows(不管何种版本)是一个成熟的操作系统,为广大客户服务了 ...
- 非常好的dllimport 文章--在 C# 中通过 P/Invoke 调用Win32 DLL
http://msdn.microsoft.com/zh-cn/library/aa686045.aspx 在 C# 中通过 P/Invoke 调用Win32 DLL 发布日期 : 1/13/2005 ...
- C#中使用Win32和其他库
C# 用户经常提出两个问题:"我为什么要另外编写代码来使用内置于 Windows 中的功能?在框架中为什么没有相应的内容可以为我完成这一任务?"当框架小组构建他们的 .NET 部分 ...
- Microsoft .NET Compact Framework 开发常见问题解答
这个 FAQ 有部分是通过编辑公共 .NET Compact Framework 新闻组 (microsoft.public.dotnet.framework.compactframework) 贴出 ...
- Xilium.CefGlue的入门
资源地址: 源码:https://gitlab.com/xiliumhq/chromiumembedded/cefglue 官方论坛:http://www.magpcss.org/ceforum/ ...
- 在C#程序设计中使用Win32 API
C# 用户经常提出两个问题:"我为什么要另外编写代码来使用内置于 Windows 中的功能?在框架中为什么没有相应的内容可以为我完成这一任务?"当框架小组构建他们的 .NET 部分 ...
- Attribute in C#
MSDN 中做如下定义 Attribute 类将预定义的系统信息或用户定义的自定义信息与目标元素相关联.目标元素可以是程序集.类.构造函数.委托.枚举.事件.字段.接口.方法.可移植可执行文件模块. ...
- cad.net 利用win32api实现一个命令开关参照面板
首先我要判断是否已经打开了参照面板. 然而cad自己没有相关的系统变量.这时我就需要利用到win32api来判断程序是否打开了参照面板了. 首先学习的是 https://blog.csdn.net/b ...
最新文章
- 20155307 2016-2017-2 《Java程序设计》第10周学习总结
- matlab生产正弦mif文件
- 病毒周报(091102至091108)
- AtCoder AGC037E Reversing and Concatenating
- html5media使用
- spring 启动进度_在Web浏览器中显示Spring应用程序启动的进度
- jquery项目中一些常用方法
- python调用activateMQ进行数据传输
- 烽火狼烟丨PHP远程代码执行漏洞(CVE-2022-31625、CVE-2022-31626)风险提示
- 开源OA协同办公平台使用教程:O2OA集成WPS
- php面包屑导航实现思路,简单实现面包屑导航代码
- 没有执行力,一切都是0,优秀都会沦为平庸
- python算法题_Python算法练习题:硬币数量
- 南开大学张昊计算机,纽约南开校友会隆重举办纪念南开大学建校100周年庆典
- Java程序员的规划之路
- 实现将网页多条磁力链接一次性全部下载
- Solar Tracker
- python手写板,机器语言之手写识别_源码时代Python公开课|Python培训
- [GDOI2016][树链剖分+主席树]疯狂动物城
- JS 声音提示 兼容所有浏览器