2016-06-22 28 views
0

Вот как я загружаю pdf с помощью библиотеки Google PDFIUM. Я получаю void*:не удается сохранить указатель на память

doc = FPDF_LoadDocument("media1.pdf", NULL); 

Теперь я хочу, чтобы сохранить этот документ в векторе FPDF_DOCUMENT, которая в основном void*, что я получить обратно из выше коды. Это, как я храню его в векторе:

pdfs.push_back(doc); 

Проблема заключается в том, когда я делать из области видимости этого метода, я не имею доступа к этой памяти, указываемой doc. Думаю, когда doc выходит из сферы действия, GC освобождает эту память. Я узнал об этом инструменте отладки Valgrid. doc объявляется в той же функции, что и команда для загрузки pdf.

Я в основном хочу сохранить загруженный pdf-файл, чтобы впоследствии получить доступ к нему и отобразить из него страницы.

Valgrind выход:

==4816== 64 bytes in 1 blocks are definitely lost in loss record 175 of 616 
==4816== at 0x4C2A105: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==4816== by 0x85175B: FPDFBitmap_Create (in /home/ec2-user/Vid/dist/Debug/GNU-MacOSX/video_creator_mount) 
==4816== by 0x4586A1: Blrt::PDFManager::RenderPDFPage(int, int) (PDFManager.cc:159) 

Ниже приведен способ, в PDFManager:

std::unique_ptr<Canvas::LoadedPDFInfo> PDFManager::LoadPDF(const std::vector<uint8_t>& data, size_t dataSize) 
{ 
    if(!initPDFIUM) { 
     InitPDFIUM(); 
     currentPDFHandle = 0; 
    } 

    FPDF_DOCUMENT doc; 
    // doc = FPDF_LoadMemDocument(&data[0], dataSize, nullptr); 
    doc = FPDF_LoadDocument("media1.pdf", NULL); 
    if (!doc) { 
     unsigned long err = FPDF_GetLastError(); 
     fprintf(stderr, "Load pdf docs unsuccessful: "); 
     switch (err) { 
     case FPDF_ERR_SUCCESS: 
      fprintf(stderr, "Success"); 
      break; 
     case FPDF_ERR_UNKNOWN: 
      fprintf(stderr, "Unknown error"); 
      break; 
     case FPDF_ERR_FILE: 
      fprintf(stderr, "File not found or could not be opened"); 
      break; 
     case FPDF_ERR_FORMAT: 
      fprintf(stderr, "File not in PDF format or corrupted"); 
      break; 
     case FPDF_ERR_PASSWORD: 
      fprintf(stderr, "Password required or incorrect password"); 
      break; 
     case FPDF_ERR_SECURITY: 
      fprintf(stderr, "Unsupported security scheme"); 
      break; 
     case FPDF_ERR_PAGE: 
      fprintf(stderr, "Page not found or content error"); 
      break; 
     default: 
      fprintf(stderr, "Unknown error %ld", err); 
     } 
     fprintf(stderr, ".\n"); 

     return nullptr; 
    } 
    pdfs.push_back(doc); 
    //doc = nullptr; 
    std::unique_ptr<Canvas::LoadedPDFInfo> pdfInfo(new Canvas::LoadedPDFInfo); 
    pdfInfo->handle = ++currentPDFHandle; 
    pdfInfo->totalPageNum = FPDF_GetPageCount(doc); 
     std::cout << "ERROR\n"; 
    return pdfInfo; 
} 

PDFs является вектор, объявленные в PDFManager.h:

namespace Blrt 
{ 
    class PDFManager 
    { 
     public: 
      static std::unique_ptr<Canvas::LoadedPDFInfo> LoadPDF(const std::vector<uint8_t>& data, size_t dataSize); 
      static std::unique_ptr<Canvas::TextureData> RenderPDFPage(int32_t pdfHandle, int32_t pageNum); 
      static void Dispose(); 

     private: 
      static void InitPDFIUM(); 
      static void UnsupportedHandler(UNSUPPORT_INFO*, int type); 
      static bool initPDFIUM; 
      static int32_t currentPDFHandle; 
      static std::vector<FPDF_DOCUMENT> pdfs; 
      static int32_t nextMultipleOf4(size_t num); 
    }; 
} 

Ниже приводится часть способа, в котором Я обращаюсь к pdf-файлам, чтобы получить доступ к pdf-данным, загруженным с использованием вышеупомянутого метода:

std::unique_ptr<Canvas::TextureData> PDFManager::RenderPDFPage(int32_t pdfHandle, int32_t pageNum) 
{ 

    if (pdfs[pdfHandle-1]) { 
     auto pdf = *(pdfs[pdfHandle-1]); 
     std::cout << pdfHandle << " " << pageNum << " " <<pdfs.size() << "\n"; 
     if (1 <= pageNum && pageNum <= FPDF_GetPageCount(pdf)) { 

      auto page = FPDF_LoadPage(pdf, pageNum); 

      if(page) { 
       auto textPage = FPDFText_LoadPage(page); 
       if (textPage) { 
        auto scale = 2.0; 
        auto maxTexSize = VideoCreator::VideoCreator::MaxTextureSize; 
        auto orgWidth = FPDF_GetPageWidth(page); 
        auto orgHeight = FPDF_GetPageHeight(page); 
        auto targetWidth = orgWidth * scale; 
        auto targetHeight = orgHeight * scale; 
        if (targetWidth > targetHeight) { 
         if (targetWidth > maxTexSize) { 
          scale = maxTexSize/targetWidth; 
         } 
        } else { 
         if (targetHeight > maxTexSize) { 
          scale = maxTexSize/targetHeight; 
         } 
        } 
+0

Вы можете поделиться немного больше кода? Где находится объект pdfs? – DaveyLaser

+4

нет gc в C++ – Incomputable

+0

@laser_wizard каково ваше предложение сейчас? – asad

ответ

0

Из сообщения valgrind, это не документ, который вы просачиваетесь, это растровое изображение, которое вы создаете позже. doc не очищается, так как в C++ нет gc. Вы должны сами закрыть документ.

Но, чтобы исправить ошибку, вам нужно очистить растровое изображение, которое вы создали в PDFManager.cc:159.