C#使用DllImport调用非托管的代码
2013-03-12 00:00
323 查看
C#调用非托管代码的方式主要有Com调用、DllImport方式调用、加载非托管动态链接库、直接执行机器码等方式。
现在介绍一下我自己常用的DllImport方式调用MSDN中提到的GetShortPathName方法;找到GetShortPathName的方法签名,
DWORD GetShortPathName(LPCTSTR tpszLongPath,TPTSTR lpszShortPath,DWORD cchBuffer);
非托管及托管数据类型对应关系:
LPCTSTR String
LPTSTR StringBuilder
DWORD int
DllImport的导入规则:
1、方法名与Win API完全一样。如果在C#中调用时显示完全不同的方法名称,则需要引入EntryPoint属性,使用别名显示。
2、函数除需要DllImport类修饰符外,还需要声明public static extern类型。
3、函数返回值和参数必须和调用的API的完全一样。
4、必须引入System.Runtime.InteropServices命名空间。
代码:
using System.Runtime.InteropServices;
public class Test
{
[DllImport("kernel32.dll",CharSet=CharSet.Auto,EntryPoint="GetShort")]
public static extern int GetShortPathName(
[MarshalAs(UnmanagedType.LPTStr)] String path,
[MarshalAs(UnmanagedType.LPTStr)] StringBuilder shortPath,
int shortPathLength);
}
代码调用中kernel32.dll的路径之所以没写是因为DllImport会按照以下三种顺序查找Dll:
1、exe所在目录;2、System32目录;3、环境变量目录。
MarshalAs为可选类型,因为每个数据类型都有默认的封送行为,该属性指示如何在托管代码和非托管代码之间的封送数据,可将该属性用于参数、字段和返回值。大多数情况下该属性只是用UnmanagedType枚举类型就能满足大多数非托管的数据类型,如默认情况下字符会被当作BStr传入到Dll中,可以使用MarshalAs将字符串指定为LPTStr、LPWStr或LPStr等。
DllImport可选属性解释
EntryPoint 可对方法采用不同的名称,使用别名
CharSet 函数调用使用Unicode还是Ansi
ExactSpelling False,表示让编译器自己选择使用Unicode或Ansi
CallingConvetnion 它的参数指示入口点调用的约定;不指定默认为CallingConvention.WinAPI
PreserveSig 指示方法签名应当被保留还是被转换,当被转换时它被转换为一个具有HRESULT返回值和该返回值的一个名为retval的附加输出参数的签名,默认为true。
SetLastError 指定是否保留上一次错误,默认为false
现在介绍一下我自己常用的DllImport方式调用MSDN中提到的GetShortPathName方法;找到GetShortPathName的方法签名,
DWORD GetShortPathName(LPCTSTR tpszLongPath,TPTSTR lpszShortPath,DWORD cchBuffer);
非托管及托管数据类型对应关系:
LPCTSTR String
LPTSTR StringBuilder
DWORD int
DllImport的导入规则:
1、方法名与Win API完全一样。如果在C#中调用时显示完全不同的方法名称,则需要引入EntryPoint属性,使用别名显示。
2、函数除需要DllImport类修饰符外,还需要声明public static extern类型。
3、函数返回值和参数必须和调用的API的完全一样。
4、必须引入System.Runtime.InteropServices命名空间。
代码:
using System.Runtime.InteropServices;
public class Test
{
[DllImport("kernel32.dll",CharSet=CharSet.Auto,EntryPoint="GetShort")]
public static extern int GetShortPathName(
[MarshalAs(UnmanagedType.LPTStr)] String path,
[MarshalAs(UnmanagedType.LPTStr)] StringBuilder shortPath,
int shortPathLength);
}
代码调用中kernel32.dll的路径之所以没写是因为DllImport会按照以下三种顺序查找Dll:
1、exe所在目录;2、System32目录;3、环境变量目录。
MarshalAs为可选类型,因为每个数据类型都有默认的封送行为,该属性指示如何在托管代码和非托管代码之间的封送数据,可将该属性用于参数、字段和返回值。大多数情况下该属性只是用UnmanagedType枚举类型就能满足大多数非托管的数据类型,如默认情况下字符会被当作BStr传入到Dll中,可以使用MarshalAs将字符串指定为LPTStr、LPWStr或LPStr等。
DllImport可选属性解释
EntryPoint 可对方法采用不同的名称,使用别名
CharSet 函数调用使用Unicode还是Ansi
ExactSpelling False,表示让编译器自己选择使用Unicode或Ansi
CallingConvetnion 它的参数指示入口点调用的约定;不指定默认为CallingConvention.WinAPI
PreserveSig 指示方法签名应当被保留还是被转换,当被转换时它被转换为一个具有HRESULT返回值和该返回值的一个名为retval的附加输出参数的签名,默认为true。
SetLastError 指定是否保留上一次错误,默认为false
相关文章推荐
- C#使用DllImport调用非托管的代码
- C#使用DllImport调用非托管的代码的方法
- C#使用DllImport调用非托管的代码
- C#使用DllImport调用非托管的代码
- 【转帖】C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
- 使用PInvoke实现C#调用非托管C代码DLL库
- 【转帖】C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
- C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
- C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
- C# DllImport 系统调用使用详解、托管代码的介绍、EntryPoint的使用
- C++工程代码打包的dll在C#工程上使用注意点!变量对应关系与dll调用出错情况。
- C#调用c代码生成的dll,报PInvoke 签名与非托管的目标签名不匹配
- C# DllImport 托管代码的介绍 EntryPoint的使用
- c# “XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。
- 在VS2010上使用C#调用非托管C++生成opencv代码的DLL文件
- 【C#】对“xxxx::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用。
- C#中使用DllImport调用C++dll
- C# CLRInsideOut 托管代码与非托管代码互操作,产生相关调用代码的好工具 C++ 头文件转C# 的好工具
- C#动态调用系统DLL函数的类(不使用DllImport)
- 使用C# 跨平台调用 p/invoke DllImport