为什么在后续通话中无法使用IntPtr

时间:2019-04-29 20:38:54

标签: c# c pinvoke

我的程序:

class Program {
    [DllImport("libiconvD.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr libiconv_open([MarshalAs(UnmanagedType.LPStr)]
                                          string tocode, 
                                          [MarshalAs(UnmanagedType.LPStr)] 
                                          string fromcode);

    [DllImport("libiconvD.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern ulong libiconv(IntPtr icd,
                             ref StringBuilder inbuf, ref ulong inbytesleft,
                             out StringBuilder outbuf, out ulong outbytesleft);

    [DllImport("libiconvD.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern int libiconv_close(IntPtr icd);

    static void Main(string[] args) {
        var inbuf = new StringBuilder("Rule(s): Global Tag – Refer to Print Rules – General Requirements");
        ulong inbytes = (ulong)inbuf.Length;
        ulong outbytes = inbytes;
        StringBuilder outbuf = new StringBuilder((int)outbytes);

        IntPtr icd = libiconv_open("utf8", "windows-1252");
        var rcode1 = libiconv(icd, ref inbuf, ref inbytes, out outbuf, out outbytes);
        Debug.WriteLine(rcode1);
        var rcode2 = libiconv_close(icd);
        Debug.WriteLine(rcode2);
    }//Main()
}//Program CLASS

libiconv_open()的第一次调用有效,并返回指向icd的指针。 当libiconv()的第二次调用运行时,它会在icd指针上发生访问冲突。

这是被调用的C代码:

size_t iconv (iconv_t icd,
              ICONV_CONST char* * inbuf, size_t *inbytesleft,
              char* * outbuf, size_t *outbytesleft)
{
  conv_t cd = (conv_t) icd;
  if (inbuf == NULL || *inbuf == NULL)
    return cd->lfuncs.loop_reset(icd,outbuf,outbytesleft);
  else
    return cd->lfuncs.loop_convert(icd,
                                   (const char* *)inbuf,inbytesleft,
                                   outbuf,outbytesleft);
}

enter image description here 似乎无法访问指针指向的结构中定义的函数。对于返回的指针有什么特别的事情要做,以使其在后续调用中可用。

谢谢

1 个答案:

答案 0 :(得分:0)

结果表明,对于C#,不需要使用libiconv库。只需使用Encoding类。

        static void Main(string[] args) {
            UTF8Encoding utf8 = new UTF8Encoding();
            Encoding w1252 = Encoding.GetEncoding(1252);

            string inbuf = "Rule(s): Global Tag – Refer to Print Rules – General Requirements";
            byte[] bytearray = utf8.GetBytes(inbuf);
            byte[] outbytes = Encoding.Convert(utf8, w1252, bytearray);

            Debug.WriteLine("*************************");
            Debug.WriteLine(String.Format("  Input: {0}", inbuf));
            Debug.WriteLine(String.Format(" Output: {0}", utf8.GetString(outbytes)));
            Debug.WriteLine("*************************");

        }//Main()

*************************
  Input: Rule(s): Global Tag – Refer to Print Rules – General Requirements
 Output: Rule(s): Global Tag – Refer to Print Rules – General Requirements
*************************