2015-03-04 8 views
-1

UPDATE 3-4-15: 11IS Как рекомендовал Дэвид, модифицированный PInvoke, как показано ниже, на этот раз я получаю другую ошибку «Необработанное исключение типа System.ExecutionEngineException произошло в mscorlib.dll"PInvoke - проблема при вызове функции DJVU из кода C#. Попытка прочитать или записать защищенную память

[DllImport("C:\\Program Files\\DJVULIBRE\\LIBDJVULIBRE.dll", CharSet=CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 
    private unsafe static extern int ddjvu_page_render(IntPtr page, ddjvu_render_mode_t mode, ref ddjvu_rect_t pagerect, 
       ref ddjvu_rect_t renderrect, 
       IntPtr pixelformat, 
       uint rowsize, 
       [Out][MarshalAs(UnmanagedType.LPArray)]byte[] imagebuffer); 

Спасибо, Дэвид за ценное время, думаю, близко к исправлению.

ИСТОРИЯ

Я знаю, что есть много вопросов в этой теме, но ни один из них не поможет решить эту проблему я в настоящее время сталкиваюсь.

Ниже функция API в C Язык

DDJVUAPI int 
ddjvu_page_render(ddjvu_page_t *page, 
        const ddjvu_render_mode_t mode, 
        const ddjvu_rect_t *pagerect, 
        const ddjvu_rect_t *renderrect, 
        const ddjvu_format_t *pixelformat, 
        unsigned long rowsize, 
        char *imagebuffer); 

Ниже приводится PInvoke подпись C Функция добавлена ​​в коде .NET

[DllImport("C:\\Program Files\\DJVULIBRE\\LIBDJVULIBRE.dll", CharSet=CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 
private unsafe static extern int ddjvu_page_render(IntPtr page, ddjvu_render_mode_t mode, IntPtr pagerect, 
      IntPtr renderrect, 
      IntPtr pixelformat, 
      ulong rowsize, 
      [Out][MarshalAs(UnmanagedType.LPArray)]byte[] imagebuffer); 

Ниже, как я называю эту функцию в C# код

  byte* buffer = (byte *)Memory.Alloc(nSize); 
      try 
      { 
       IntPtr ptr1 = (IntPtr)Memory.Alloc(Marshal.SizeOf(prect)); 
       Marshal.StructureToPtr(prect, ptr1, false); 

       IntPtr ptr2 = (IntPtr)Memory.Alloc(Marshal.SizeOf(rrect)); 
       Marshal.StructureToPtr(rrect, ptr2, false); 

       byte[] array = new byte[nSize]; 
       fixed (byte* p = array) Memory.Copy(buffer, p, nSize); 
       ddjvu_page_render(page, ddjvu_render_mode_t.DDJVU_RENDER_MASKONLY, ptr1, ptr2, fmt, (ulong)stride, array); 
      } 
      finally 
      { 
       Memory.Free(buffer); 
      } 

вызов ddjvu_page_render в коде выше бросает «Попытка чтения или записи защищенной памяти. Это часто свидетельствует о том, что другая память повреждена ». До этого сообщения я, должно быть, пробовал все, что мог найти в различных блогах. Цените любую помощь, это почти день, когда я не знаю, ваша своевременная помощь могла бы сэкономить работа

ОБНОВЛЕНИЕ 3-4-15: 7: 44IS Этот код использует DJVULibre

UPDATE 3-4-15: 8: 35IS

Вот код, я имею в Форма загрузки

ctx = ddjvu_context_create(System.AppDomain.CurrentDomain.FriendlyName); 
    if (ctx != null) 
    { 
     string djFile = "C:\\Users\\rammohan.chavakula\\Documents\\eiasample.djvu"; 
     doc = ddjvu_document_create_by_filename(ctx, djFile, 100); 
     if (doc != null) 
     { 
      while (ddjvu_job_status(ddjvu_document_job(doc)) >= ddjvu_status_t.DDJVU_JOB_OK) 
       SpinDdjvuMessageLoop(ctx, true); 

      int pageCount = ddjvu_document_get_pagenum(doc); 
      mediaboxes = new Rectangle[pageCount]; 
      for (int i = 0; i < pageCount; i++) 
      { 
       ddjvu_status_t status; 
       ddjvu_pageinfo_t info = new ddjvu_pageinfo_t(); 

       while ((status = ddjvu_document_get_pageinfo_imp(doc, i, ref info, (uint)System.Runtime.InteropServices.Marshal.SizeOf(info))) < ddjvu_status_t.DDJVU_JOB_OK) 
        SpinDdjvuMessageLoop(ctx, true); 
       if (status != ddjvu_status_t.DDJVU_JOB_OK) 
        continue; 

       mediaboxes[i] = new Rectangle(0, 0, info.width/info.dpi, 
          info.height/info.dpi); 

      } 

     } 
     ddjvu_context_release(ctx); 
    } 

В OnPaint функции я это ниже кода

 if (doc == null) 
     { 
      base.OnPaint(e); 
      return; 
     } 
     Rectangle pageRc = PageMediabox(1); 
     Rectangle screen = Transform(pageRc, 1, zoom, rotation, false); 
     Rectangle full = Transform(PageMediabox(1), 1, zoom, rotation, false); 
     full.Intersect(screen); 

     IntPtr page = ddjvu_page_create_by_pageno(doc, 1); 
     if (page == null) 
     { 
      base.OnPaint(e); 
      return; 
     } 
     int rotation4 = (((-rotation/90) % 4) + 4) % 4; 
     ddjvu_page_set_rotation(page, (ddjvu_page_rotation_t)rotation4); 

     while (ddjvu_job_status(ddjvu_page_job(page)) >= ddjvu_status_t.DDJVU_JOB_OK) 
      SpinDdjvuMessageLoop(ctx, true); 
     if (ddjvu_job_status(ddjvu_page_job(page)) >= ddjvu_status_t.DDJVU_JOB_FAILED) 
     { 
      base.OnPaint(e); 
      return; 
     } 
     IntPtr fmt = ddjvu_format_create(ddjvu_format_style_t.DDJVU_FORMAT_BGR24, 0, (UIntPtr)null); 
     ddjvu_format_set_row_order(fmt, /* top_to_bottom */1); 
     ddjvu_rect_t prect = new ddjvu_rect_t(full.X, full.Y, (uint)full.Width, (uint)full.Height); 
     ddjvu_rect_t rrect = new ddjvu_rect_t(screen.X, 2 * full.Y + screen.Y + full.Height - screen.Height, (uint)screen.Width, (uint)screen.Height); 


     int stride = ((screen.Width * 3 + 3)/4) * 4; 
     //byte tmp; 
     ////ScopedMem<char> bmpData(SAZA(char, stride * (screen.dy + 5))); 
     //for (int y = 0; y < rrect.h; y++) { 
     // int step_y = y * SCREEN_WIDTH; 
     // for (int x=0; x < rrect.w; x++) { 
     //  tmp = (byte)((imagebuf[x + step_y] >> 5) << 5); 
     // } 
     //} 
     int rowsize = mediaboxes[0].Width * 3; 
     int nSize = rowsize * (mediaboxes[0].Height) * 10; 

     unsafe 
     { 
      byte* buffer = (byte *)Memory.Alloc(nSize); 
      try 
      { 
       IntPtr ptr1 = (IntPtr)Memory.Alloc(Marshal.SizeOf(prect)); 
       Marshal.StructureToPtr(prect, ptr1, false); 

       IntPtr ptr2 = (IntPtr)Memory.Alloc(Marshal.SizeOf(rrect)); 
       Marshal.StructureToPtr(rrect, ptr2, false); 

       byte[] array = new byte[nSize]; 
       fixed (byte* p = array) Memory.Copy(buffer, p, nSize); 
       ddjvu_page_render(page, ddjvu_render_mode_t.DDJVU_RENDER_MASKONLY, ptr1, ptr2, fmt, (ulong)stride, array); 
      } 
      finally 
      { 
       Memory.Free(buffer); 
      } 

ddjvu_page_render должен возвращать произвольные данные страницы, которая должна быть оказана в данной области прямоугольника. После того, как после того, что я должен быть в состоянии создать изображение из произвольных данных & отображения на экране

+0

Невозможно ответить. Мы не знаем, что находится на другой стороне взаимодействия. Не нужно и небезопасно. Конечно, ваш текущий код не будет компилироваться без него, но вам не нужно писать его таким образом. –

+0

Дэвид, код успешно скомпилирован при ошибке выполнения при вызове функции ddjvu_page_render. Этот код .NET использует библиотеку DJVULibre C++ – Naga

+0

Как я уже сказал, невозможно ответить, когда мы можем видеть только одну сторону взаимодействия. Пожалуйста, не ожидайте, что мы проведем много исследований. Четко представляйте обе стороны взаимодействия, со всей информацией, которую мы должны уметь критиковать ваш разговор. –

ответ

0

Вот как я написал бы р/взывать:

[DllImport(dllname, CharSet=CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 
private static extern int ddjvu_page_render(
    [In] IntPtr page, 
    [In] ddjvu_render_mode_t mode, 
    [In] ref ddjvu_rect_t pagerect, 
    [In] ref ddjvu_rect_t renderrect, 
    [In] ref ddjvu_format_t pixelformat, 
    [In] uint rowsize, 
    [Out] byte[] imagebuffer 
); 

Обратите внимание, что я перестал использовать unsafe, и я позволяя маршалисту обрабатывать структуры автоматически.

Есть немало предположений здесь, что я не могу подтвердить:

  • Вызывающих конвенций. Это может быть не cdecl. Заголовок C++ будет иметь окончательный ответ.
  • Первый параметр - тип типа void*, я полагаю.
  • ddjvu_render_mode_t - это перечисление, которое вы перевели правильно.
  • Три параметра ref являются структурами, передаваемыми по ссылке. Я не могу проверить, правильно ли вы перевели их.

Вызов этой функции будет что-то вроде этого:

byte[] imagebuffer = new byte[nSize]; 
int retval = ddjvu_page_render(
    page, 
    ddjvu_render_mode_t.DDJVU_RENDER_MASKONLY, 
    ref prect, 
    ref rrect, 
    ref fmt, 
    (uint)stride, 
    imagebuffer 
); 
if (retval != ??) 
    // handle error 

Это довольно широкая кисть ответ. Надеюсь, он укажет вам в правильном направлении. Я не думаю, что все ваши проблемы будут решены этим.

+0

David, я внес изменения точно так же, как вы предлагали, за исключением того, что для ddjvu_format_t, для которого не удалось найти его определение в справочнике библиотек C++, вместо этого я все еще использую тот же IntPtr, из окна отладки я мог видеть действительный указатель, возвращаемый ddjvu_format_create, который вызывается до этой функции. Результат такой же, я получаю «Необработанное исключение типа System.ExecutionEngineException, произошедшее в mscorlib.dll». Вызывающее соглашение - это CDecl, как я мог подтвердить из ddjvuapi.h. Еще раз спасибо за ваше внимание и внимание. – Naga

+0

Тогда у вас есть проблема в коде. Как я объяснил в своем ответе, все еще есть большие части этого, которые я не вижу. –