2010-06-02 96 views
0

我试图访问某个Ghostscript的功能,像这样:C#互操作使用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

UnmanagedType.LPTStr是依赖于平台的(ANSI在Win98上,Unicode在NT/XP上)。你的C++结构使用char *类型,所以你可能需要UnmanagedType.LPStr

此外,C#中的long为64位,而C++中的长为32位。您可能想在您的C#代码中使用int

+0

哦,那么简单。谢谢。 – Amy 2010-06-02 19:42:28