C # взаимодействие с Ghostscript - PullRequest
0 голосов
/ 02 июня 2010

Я пытаюсь получить доступ к некоторым функциям Ghostscript, например:

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

Это соответствует этим определениям из заголовка iapi.h из 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);

Но мой код ничего не читает в строковые поля. Если я добавлю 'ref' к функции, она будет читать как бред. Тем не менее, следующий код читает данные просто отлично:

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

Так что же я делаю не так с маршалингом?

1 Ответ

1 голос
/ 02 июня 2010

UnmanagedType.LPTStr зависит от платформы (ANSI на Win98, Unicode на NT / XP). В вашей структуре C ++ используется тип char *, поэтому вы, вероятно, хотите вместо нее UnmanagedType.LPStr.

Кроме того, long в C # составляет 64 бита, в то время как long в C ++ составляет 32 бита. Вы, вероятно, хотите использовать int в своем коде C #.

...