2016-06-22 13 views
0

これは、GoogleのPDFIUMライブラリを使用してPDFを読み込む方法です。私はvoid*を受け取る:メモリへのポインタを保持できません

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

は、今私は基本的に私は上記のコードから戻って受信void*あるFPDF_DOCUMENTのベクトルでこの文書を保存したいです。私はベクトルでそれを保存していますどのようにこれは、次のとおりです。

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; 
} 

PDFファイルが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データにアクセスするためにpdfsにアクセスしています:

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

C++にgcがありません – Incomputable

+0

@laser_wizard今あなたの提案は何ですか? – asad

答えて

0

valgrindメッセージからは、あなたが流出しているドキュメントではなく、後で作成するビットマップです。 docは、C++にgcが存在しないため、クリーンアップされません。自分で文書を閉じる必要があります。

しかし、このエラーを修正するには、PDFManager.cc:159で作成したビットマップをクリーンアップする必要があります。

関連する問題