2010-06-02 7 views
0

Je suis en train d'accéder à certaines fonctions Ghostscript comme ceci:C# Interop avec 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)); 

Cela correspond à ces définitions de l'en-tête iapi.h de 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); 

Mais mon code ne lit rien dans les champs de chaînes. Si j'ajoute 'ref' à la fonction, il lit charabia. Cependant, le code suivant lit très bien les données:

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

Alors, qu'est-ce que je fais de mal à marshaling?

Répondre

1

UnmanagedType.LPTStr dépend de la plate-forme (ANSI sous Win98, Unicode sous NT/XP). Votre structure C++ utilise le type char *, donc vous voulez probablement UnmanagedType.LPStr à la place.

De plus, un long en C# est 64 bits alors qu'un long en C++ est de 32 bits. Vous voulez probablement utiliser int dans votre code C#.

+0

Oh, si simple. Je vous remercie. – Amy