作用:
MarshalAs属性指示如何在托管代码和非托管代码之间封送数据。
使用方法:
[MarshalAs(UnmanagedType unmanagedType, 命名参数)]
实际上相当于构造一个MarshalAsAttribute类的对象
常用的UnmanagedType枚举值:
BStr 长度前缀为双字节的 Unicode 字符串;
LPStr 单字节、空终止的 ANSI 字符串。;
LPWStr 一个 2 字节、空终止的 Unicode 字符串;
ByValArray 用于在结构中出现的内联定长字符数组,应始终使用MarshalAsAttribute的SizeConst字段来指示数组的大小。
注意:
在用Marshal.SizeOf(),即获取对象的非托管大小时,获得的是自己定义的大小;
但在实际处理的时候,是按照实际的大小来获取的
示例:
定义一个固定大小的结构体,代码如下:
结构的声明:
struct Info
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public char[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public char[] cipher;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public char[] signature;
}
结构的使用:
Info myInfo;
myInfo.name = name.ToCharArray();
myInfo.cipher = cipher.ToCharArray();
myInfo.signature = signature.ToCharArray();
注意:
int size = Marshal.SizeOf(myInfo);
实际应用中:
using System;
using System.Runtime.InteropServices;
namespace tetris
{
/// <summary>
/// SoundPlayer
/// </summary>
public class SoundPlayer
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
private string mciStatus = "";
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
private string shortFileName = "";
[DllImport("winmm.dll", EntryPoint = "mciSendString", SetLastError = true, CharSet = CharSet.Auto)]
private static extern long mciSendString(
string lpstrCommand,
string lpstrReturnString,
long uReturnLength,
long hwndCallback
);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetShortPathName(
string lpszLongPath,
string shortFile,
int cchBuffer
);
private string File;
private string Alias;
private string status = "close";
public SoundPlayer(string strFileName, string strAliasName)
{
this.File = LongNameToShortName(strFileName);
this.Alias = strAliasName;
status = "close";
}
private string LongNameToShortName(string strFileName)
{
shortFileName = shortFileName.PadLeft(260, Convert.ToChar(" "));
GetShortPathName(strFileName, shortFileName, shortFileName.Length);
return GetCurrPath(shortFileName);
}
private string GetCurrPath(string name)
{
if (name.Length < 1) return "";
name = name.Trim();
name = name.Substring(0, name.Length - 1);
return name;
}
public string FileName
{
get
{
return File;
}
set
{
File = LongNameToShortName(value);
}
}
public string AliasName
{
get
{
return Alias;
}
}
public bool PlaySound()
{
if (PlayFile() == true)
{
return true;
}
else
{
return false;
}
}
public bool StopSound()
{
StopFile();
return false;
}
private bool PlayFile()
{
bool returnValue;
long lRet;
try
{
StopFile();
lRet = mciSendString("open " + this.File + " alias " + Alias, "", 0, 0);
lRet = mciSendString("play " + Alias, "", 0, 0);
returnValue = (lRet == 0);
status = "play";
}
catch (Exception)
{
return false;
}
return true;
}
public void CloseAudio()
{
mciSendString("close all", "", 0, 0);
status = "close";
}
private bool StopFile()
{
long lRet;
try
{
lRet = mciSendString("stop " + Alias, "", 0, 0);
lRet = mciSendString("close " + Alias, "", 0, 0);
status = "stop";
return true;
}
catch (Exception)
{
return false;
}
}
public bool IsPlaying
{
get
{
if (status != "play")
return false;
mciStatus = "";
mciStatus = mciStatus.PadLeft(128, Convert.ToChar(" "));
mciSendString("status " + this.Alias + " mode", mciStatus, 128, 0);
return mciStatus.Substring(0, 7).ToLower() == "playing".ToLower();
}
}
}
}