传递结构成员
以下示例将显示如何在托管代码中定义 Point 和 Rect 类型,并将这些类型当作 User32.dll 文件中 PtInRect 函数的参数进行传递。PtInRect 具有以下非托管签名:BOOL PtInRect(const RECT *lprc, POINT pt);
请注意,由于函数需要指向 RECT 类型的指针,必须通过引用来传递 Rect 结构。[Visual Basic]
Imports System.Runtime.InteropServices<StructLayout(LayoutKind.Sequential)> Public Structure Point
    Public x As Integer
    Public y As Integer
End StructurePublic Structure <StructLayout(LayoutKind.Explicit)> Rect
    <FieldOffset(0)> Public left As Integer
    <FieldOffset(4)> Public top As Integer
    <FieldOffset(8)> Public right As Integer
    <FieldOffset(12)> Public bottom As Integer
End StructureClass Win32API    
    Declare Auto Function PtInRect Lib "user32.dll" _
    (ByRef r As Rect, p As Point) As Boolean
End Class
[C#]
using System.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential)]
public struct Point {
      public int x;
      public int y;
}   [StructLayout(LayoutKind.Explicit]
public struct Rect {
      [FieldOffset(0)] public int left;
      [FieldOffset(4)] public int top;
      [FieldOffset(8)] public int right;
      [FieldOffset(12)] public int bottom;
}   class Win32API {
   [DllImport("User32.dll")]
   public static extern Bool PtInRect(ref Rect r, Point p);
}
传递类成员
只要类具有固定的成员布局,就可以将类的成员传递给非托管的 DLL 函数。以下示例将说明如何将 MySystemTime 类的成员(按连续的顺序定义)传递给 User32.dll 文件中的 GetSystemTime。GetSystemTime 具有以下非托管签名:void GetSystemTime(SYSTEMTIME* SystemTime);
与值类型不同,类始终要通过引用来传递。[Visual Basic]
Imports System.Runtime.InteropServices
Imports Microsoft.VisualBasic<StructLayout(LayoutKind.Sequential)> Public Class MySystemTime
   Public wYear As Short
   Public wMonth As Short
   Public wDayOfWeek As Short 
   Public wDay As Short
   Public wHour As Short
   Public wMinute As Short
   Public wSecond As Short
   Public wMiliseconds As Short
End ClassPublic Class Win32
   Declare Auto Sub GetSystemTime Lib "Kernel32.dll"(sysTime _
      As MySystemTime)
   Declare Auto Function MessageBox Lib "User32.dll"(hWnd As Integer, _
      txt As String, caption As String, Typ As Integer) As Integer
End ClassPublic Class TestPlatformInvoke    
   Public Shared Sub Main()
           Dim sysTime As New MySystemTime()
           Win32.GetSystemTime(sysTime)           Dim dt As String
           dt = "System time is:" & ControlChars.CrLf & _
            "Year: " & sysTime.wYear & _
              ControlChars.CrLf & "Month: " & sysTime.wMonth & _
              ControlChars.CrLf & "DayOfWeek: " & sysTime.wDayOfWeek & _
              ControlChars.CrLf & "Day: " & sysTime.wDay
         Win32.MessageBox(0, dt, "Platform Invoke Sample", 0)      
   End Sub
End Class
[C#]
[StructLayout(LayoutKind.Sequential)]
public class MySystemTime {
   public ushort wYear; 
   public ushort wMonth;
   public ushort wDayOfWeek; 
   public ushort wDay; 
   public ushort wHour; 
   public ushort wMinute; 
   public ushort wSecond; 
   public ushort wMilliseconds; 
}
class Win32API {
   [DllImport("Kernel32.dll")]
   public static extern void GetSystemTime(MySystemTime st);
}

解决方案 »

  1.   

    结构定义:
    [StructLayout(LayoutKind.Sequential)]
    public struct Card
    {
    uint AccountNo;
    [ MarshalAs( UnmanagedType.ByValArray, SizeConst=21 )]
    byte StudentNo[21]; 
    short RetCode; 
    }
    函数定义:
    [DllImport("xxx.dll")]
    public extern int CardOper(ref Card card);
    调用:
    {
    ...
    Card card = new Card();
    //Init card
    int ret = CardOper(ref card);
    }
      

  2.   

    另外,如果你要传的字符串中有中文,则需要用
    Encoding.GetEncoding("GB2312").GetBytes(string)来取得该串的byte数组
    否则用Encoding.ASCII.GetBytes(string)