System.Runtime.InteropServices浅见

本文介绍如何使用System.Runtime.InteropServices实现在托管与非托管代码间互相调用,通过具体实例展示了如何定义结构体、使用DllImport及MarshalAs特性来实现跨平台方法调用。
摘要由CSDN通过智能技术生成

System.Runtime.InteropServices提供了相应的类或者方法来支持托管/非托管模块间的互相调用。
System.Runtime.InteropServices中几个比较重要的类:
DllImportAttribute : 该类提供对非托管动态链接库进行引用的方法,并告诉我们的编译器该程序的静态入口点是非托管的动态连接库,它的静态属性提供了对非托管动态链接库进行调用所必需的信息,作为最基本的要求,该类应该定义提供调用的非托管动态链接库的名称。成员详细信息
StructLayoutAttribute: 该类使得用户可以控制类或结构的数据字段的物理布局。

None.gif [StructLayout(LayoutKind.Explicit, Size = 16 , CharSet = CharSet.Ansi)]
None.gif
public   class  MySystemTime 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   [FieldOffset(
0)]public ushort wYear; 
InBlock.gif   [FieldOffset(
2)]public ushort wMonth;
InBlock.gif   [FieldOffset(
4)]public ushort wDayOfWeek; 
InBlock.gif   [FieldOffset(
6)]public ushort wDay; 
InBlock.gif   [FieldOffset(
8)]public ushort wHour; 
InBlock.gif   [FieldOffset(
10)]public ushort wMinute; 
InBlock.gif   [FieldOffset(
12)]public ushort wSecond; 
InBlock.gif   [FieldOffset(
14)]public ushor wMilliseconds; 
ExpandedBlockEnd.gif}
MarshalAsAttribute : 指示如何在托管代码和非托管代码之间封送数据。下面是MSDN给出的示例代码:
None.gif [C#] 
None.gif
// Applied to a parameter.
None.gif
   public   void  M1 ([MarshalAs(UnmanagedType.LPWStr)]String msg);
None.gif
// Applied to a field within a class.
ExpandedBlockStart.gifContractedBlock.gif
   class  MsgText  dot.gif {
InBlock.gif    [MarshalAs(UnmanagedType.LPWStr)] Public String msg;
ExpandedBlockEnd.gif  }

None.gif
// Applied to a return value.
None.gif
[ return : MarshalAs(UnmanagedType.LPWStr)]
None.gif
public  String GetMessage

一个将三个类综合运用的实例:调用kernel32.dll中的非托管方法"GetSystemTime"将系统时间返回给定制的类MySystemTime并执行输出.
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
using  System.Runtime.InteropServices;
None.gif
None.gif
namespace  DllImportTest
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//**//**//// <summary>
InBlock.gif    
/// 定义一个用于接收非托管API方法返回值的类
InBlock.gif    
/// StructLayout定义了该类的各个成员在物理上的排列方式
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    [StructLayout(LayoutKind.Explicit, Size = 16, CharSet = CharSet.Ansi)]
InBlock.gif    
public class MySystemTime
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        [FieldOffset(
0)]
InBlock.gif        
public ushort wYear;
InBlock.gif        [FieldOffset(
2)]
InBlock.gif        
public ushort wMonth;
InBlock.gif        [FieldOffset(
4)]
InBlock.gif        
public ushort wDayOfWeek;
InBlock.gif        [FieldOffset(
6)]
InBlock.gif        
public ushort wDay;
InBlock.gif        [FieldOffset(
8)]
InBlock.gif        
public ushort wHour;
InBlock.gif        [FieldOffset(
10)]
InBlock.gif        
public ushort wMinute;
InBlock.gif        [FieldOffset(
12)]
InBlock.gif        
public ushort wSecond;
InBlock.gif        [FieldOffset(
14)]
InBlock.gif        
public ushort wMilliseconds;
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//**//**//// <summary>
InBlock.gif    
/// 用LibWrapper的静态方法来调用非托管API方法"GetSystemTime"
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    class LibWrapper
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        [DllImport(
"kernel32.dll", EntryPoint = "GetSystemTime")]
InBlock.gif        
//如果定义的方法名称与要进行封装的非托管API方法不同则需要在DLLImport中指定入口点.
InBlock.gif
        public static extern void gettime([MarshalAs(UnmanagedType.LPStruct)]MySystemTime st);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
class TestApplication
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MySystemTime sysTime 
= new MySystemTime();
InBlock.gif                
//LibWrapper.GetSystemTime(sysTime);
InBlock.gif
                LibWrapper.gettime(sysTime);
InBlock.gif                Console.WriteLine(
"The System time is {0}/{1}/{2} {3}:{4}:{5}", sysTime.wDay,
InBlock.gif                   sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (TypeLoadException e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(
"TypeLoadException : " + e.Message);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(
"Exception : " + e.Message);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

None.gif
62689.html

hobo 2009-11-19 21:24 发表评论

转载于:https://www.cnblogs.com/zhouweiwei/archive/2009/11/19/1866496.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值