c# interop with ghostscript
- by yodaj007
I'm trying to access some Ghostscript functions like so:
[DllImport(@"C:\Program Files\GPLGS\gsdll32.dll", EntryPoint = "gsapi_revision")]
public static extern int Foo(gsapi_revision_t x, int len);
public struct gsapi_revision_t
{
    [MarshalAs(UnmanagedType.LPTStr)]
    string product;
    [MarshalAs(UnmanagedType.LPTStr)]
    string copyright;
    long revision;
    long revisiondate;
}
public static void Main()
{
    gsapi_revision_t foo = new gsapi_revision_t();
    Foo(foo, Marshal.SizeOf(foo));
This corresponds with these definitions from the iapi.h header from ghostscript:
typedef struct gsapi_revision_s {
    const char *product;
    const char *copyright;
    long revision;
    long revisiondate;
} gsapi_revision_t;
GSDLLEXPORT int GSDLLAPI 
gsapi_revision(gsapi_revision_t *pr, int len);
But my code is reading nothing into the string fields.  If I add 'ref' to the function, it reads gibberish.  However, the following code reads in the data just fine:
public struct gsapi_revision_t
{
    IntPtr product;
    IntPtr copyright;
    long revision;
    long revisiondate;
}
public static void Main()
{
    gsapi_revision_t foo = new gsapi_revision_t();
    IntPtr x = Marshal.AllocHGlobal(20);
    for (int i = 0; i < 20; i++)
        Marshal.WriteInt32(x, i, 0);
    int result = Foo(x, 20);
    IntPtr productNamePtr = Marshal.ReadIntPtr(x);
    IntPtr copyrightPtr = Marshal.ReadIntPtr(x, 4);
    long revision = Marshal.ReadInt64(x, 8);
    long revisionDate = Marshal.ReadInt64(x, 12);
    byte[] dest = new byte[1000];
    Marshal.Copy(productNamePtr, dest, 0, 1000);
    string name = Read(productNamePtr);
    string copyright = Read(copyrightPtr);
}
    public static string Read(IntPtr p)
    {
        List<byte> bits = new List<byte>();
        int i = 0;
        while (true)
        {
            byte b = Marshal.ReadByte(new IntPtr(p.ToInt64() + i));
            if (b == 0)
                break;
            bits.Add(b);
            i++;
        }
        return Encoding.ASCII.GetString(bits.ToArray());
    }
So what am I doing wrong with marshaling?