假设在LegacyLib.dll中给出以下签名:
int Login(SysInst *inst, char username[8], char password[6]);
在C#中编组此函数的简单方法是:
[DllImport("LegacyLib.dll", CharSet=CharSet.Ansi)]
public static extern int Login(ref SysInst inst, string username, string password);
以这种天真的方式执行此操作的问题是,我们传递到username
或password
参数的托管字符串可能比数组边界长,这可能会导致缓冲区溢出在LegacyLib.dll中。
有没有更好的方法来克服这个问题?即,我可以使用任何快速[MarshalAs(…)]
魔法来对抗它吗?
答案 0 :(得分:1)
我目前解决问题的方法如下:
public class LegacyLibWrapper {
// Don't expose the function...
[DllImport("LegacyLib.dll", EntryPoint = "Login", CharSet = CharSet.Ansi)]
static extern int UnmanagedLogin (ref SysInst inst, string username, string password);
// ... we write a proxy function that does the truncation to passed to LegacyLib
public static int Login(ref SysInst inst, string username, string password)
{
return UnmanagedLogin(inst, Truncate(username, 7), Truncate(password, 5));
}
// A utility function to do string truncation
private function Truncate(string originalString, int maxLength)
{
if (originalString.Length < maxLength)
{
return originalString;
}
else
{
return originalString.Substring(0, maxLength);
}
}
}
...老实说,为了解决这个问题需要编写额外的代码行,感觉有点拖累,我想知道是否有更好的方法来实现它?