views:

80

answers:

1

Let say that given the following signature in LegacyLib.dll:

int Login(SysInst *inst, char username[8], char password[6]);

The simple way to marshal this function in C# would be:

[DllImport("LegacyLib.dll", CharSet=CharSet.Ansi)]
public static extern int Login(ref SysInst inst, string username, string password);

The problem of doing it in a such a naive way is that the managed string we passed into the username or password parameter could be longer than the array bounds and this could potentially cause a buffer overrun in LegacyLib.dll.

Is there a better way which overcomes this problem? i.e. is there any quick [MarshalAs(…)] magic that I could use to counter that?

A: 

My current approach to solving the problem is as follows:

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);
        }
    }
}

... honestly it felt a bit of a drag having to write extra lines of code to get around that, I wonder whether there's a better way round of achieving it?

Seh Hui 'Felix' Leong