Конференция ".Net" » Указатели Delphi <-> Sharp
 
  • Джо © (21.12.07 00:15) [0]
    Есть библиотека на Delphi Win32. Из нее экспортируются такие функции (схематично):
    function GetString (var P: PChar): dword;
    function FreeString (var P: PChar)

    (Библиотеку менять нельзя).
    Первая функция выделяет внутри себя необходимый блок памяти (GetMem), записывает в него некую строку и в параметре P передает ссылку на него.
    Вторая функция принимает указатель на эту область памяти и освобождает ее (FreeMem).

    Для импорта в Шарп (2.0) делаю обертку:

       public static class LibWrap
       {
           [DllImport(LibName, CharSet = CharSet.Ansi)]
           public static extern int GetString(out String p);
       }


    Тут все понятно. Непонятно, можно ли (и каким образом?) импортировать вторую функцию.
    То, что библиотека спроектирована не слишком хорошо — это я и так знаю, но, что имею, то имею.
  • Канадец (21.12.07 06:28) [1]
    Возвращай из первой ф-ции IntPtr. Далее Marshal.PtrToStringAnsi и тут же отдавай  этот IntPtr на убиение во вторую ф-цию дабы избежать memory leaks.

       public static class LibWrap
      {
          [DllImport(LibName, CharSet = CharSet.Ansi)]
          public static extern int GetString(out IntPtr p);

          [DllImport(LibName, CharSet = CharSet.Ansi)]
          public static extern void FreeString (IntPtr p);
      }

  • Джо © (21.12.07 13:32) [2]
    Спасибо, видимо, так и придется сделать. Жаль утраты типизации, документация станет совсем кошмарной, но что поделаешь.
  • Канадец (21.12.07 16:07) [3]
    Зачем же утрачивать типизацию. Можно и без утраты. Просто вторая ф-ция не нужна. Я не знаю всех подробностей, но код может выглядить приблизительно так:

       public static class LibWrap
       {
           public static int GetString(out string p)
           {
               IntPtr ptr = IntPtr.Zero;
               int someValue = GetString(out ptr);
               p = Marshal.PtrToStringAnsi(ptr);
               FreeString(ptr);
               return someValue;
           }


           [DllImport("LibName", CharSet = CharSet.Ansi)]
           private static extern int GetString(out IntPtr p);

           [DllImport("LibName", CharSet = CharSet.Ansi)]
           private static extern void FreeString(IntPtr p);
       }

  • Джо © (21.12.07 21:10) [4]
    А, идею понял, спасибо.
    Но, слава всемогущему, сегодня добился изменений в библиотеке, сменили способ работы с памятью, так оно и к лучшему :)
    Еще раз спасибо.
 
Конференция ".Net" » Указатели Delphi <-> Sharp
Есть новые Нет новых   [118621   +7][b:0][p:0.002]