Почему IntPtr не может быть использован при последующем вызове - PullRequest
0 голосов
/ 29 апреля 2019

Моя программа:

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 голосов
/ 01 мая 2019

Оказывается, что использование библиотеки libiconv в C # не нужно. Просто используйте класс 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
*************************
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...