I'm trying to compile a project using Code::Blocks with a MinGW compiler (Windows XP).

I have included the correct library file from boost and set the right include path but it doesn't seem to make any difference.

Here's the error. The impression I'm getting is PdfContentsGraph class is not initializing properly.
as the words "error: expected ';' before 'grapher' (grapher is the instance of the class PdfContentsGraph), indicate that the class PdfContentsGraph isn't recognized as a class when it needs to be. This error is in main.

Any clues as to what causes this?

2. C:\Documents and Settings\xxxx\My Documents\codeblock files\test3pdf\main.cpp||In function 'int main(int, char**)':|
3. C:\Documents and Settings\xxxx\My Documents\codeblock files\test3pdf\main.cpp|87|**error**: 'PdfContentsGraph' was not declared in this scope|
4. C:\Documents and Settings\xxxx\My Documents\codeblock files\test3pdf\main.cpp|87|**error**: expected ';' before 'grapher'|
5. ||=== Build finished: 2 errors, 0 warnings ===|

Did you make sure the include the header required for the class PdfContentsGraph? Which is:

#include "PdfContentsGraph.h"

using namespace PoDoFo;  // <-- this is needed too, otherwise you have to use it as 'PoDoFo::PdfContentsGraph'.

The error message is exactly what you get when you forget to include the right header or specify / use the namespace in which the class is. Note that the "expected ';'" part is meaningless, it's just a result of the compiler being a bit confused after it could not recognize the class given in the line of code.

Also, I hope that you realized that this particular example (from PoDoFo) requires you to also download the PdfContentsGraph.h header and its source, as seen in the bottom of this page.

Edited 4 Years Ago by mike_2000_17

Thanks, but I've done all these things.

The files on the link also come in the PODOFO source code pack so I have all of them in my project. As for the #includes and namespace, they are all there too. I'm sure it's something simple, but I just can't find it. A real mystery.

No matter what I include or put in the linker / search directories / global variables it comes back to the same thing. (the error) when I try to compile.

I've provided a screenshot of a line I typed into main so show that the Podofo Namespace is recognised. That line PoDoFo::PdfContentsGraph is just to show that that object is visible in main.

PdfContentsGraph-giff

I assume this means it's unsolvable? The class PdfContentsGraph can be seen but it can't be seen? If it can't be seen the why can it be seen?

Here is the full compiler log. It doesn't really tell me anything new but maybe someone out there can make sense of it? Another thing.... PdfContentsGraph is reliant on Boost. Particularly the Boost Graph Library. I've build that and included that in my Linker path but could there potentially be something wrong with that build which is stopping PdfContentsGraph from being recognized? Just a thought.

Build started on: 22-11-2012 at 18:52.39
Build ended on: 22-11-2012 at 18:52.56
-------------- Build: Debug in PodofoBoost ---------------
mingw32-g++.exe -Wall -fexceptions -g -DHAVE_BOOLEAN -IC:\freetype-2.4.10\include -IC:\jpeg-6b -IC:\libffi-3.0.10\include -IC:\podofo-0.9.1\src -IC:\zlib -IC:\libpng -IC:\CodeBlocks\MinGW\include -IC:\podofo-0.9.1 -IC:\Boost\include\boost-1_52 -IC:\podofo-0.9.1\examples\pdfcontentsgraph -IC:\podofo-0.9.1\podofo -IC:\freetype-2.4.10\include -IC:\jpeg-6b -IC:\libffi-3.0.10\include -IC:\podofo-0.9.1\src -IC:\zlib -IC:\libpng -IC:\CodeBlocks\MinGW\include -IC:\podofo-0.9.1 -IC:\podofo-0.9.1\examples\pdfcontentsgraph -IC:\podofo-0.9.1\tools\podofotxtextract -IC:\podofo-0.9.1\podofo -IC:\podofo-0.9.1\podofo\base -IC:\Boost\include\boost-1_52 -IC:\podofo-0.9.1\src\base -IC:\CodeBlocks\sqlite_ -IC:\podofo-0.9.1\podofo-debug\src\CMakeFiles\podofo_static.dir\doc -IC:\podofo-0.9.1\podofo-debug\src\CMakeFiles\podofo_static.dir\base -IC:\podofo-0.9.1\src -c "C:\Documents and Settings\xxxx\My Documents\codeblock files\PodofoBoost\main.cpp" -o obj\Debug\main.o
C:\Documents and Settings\xxxx\My Documents\codeblock files\PodofoBoost\main.cpp: In function 'int main(int, char**)':
C:\Documents and Settings\xxxx\My Documents\codeblock files\PodofoBoost\main.cpp:84: error: 'PdfContentsGraph' was not declared in this scope
C:\Documents and Settings\xxxx\My Documents\codeblock files\PodofoBoost\main.cpp:84: error: expected ';' before 'grapher'
Process terminated with status 1 (0 minutes, 13 seconds)
2 errors, 0 warnings

Edited 4 Years Ago by daino

I really don't know how this works. If the class PdfContentsGraph needs the 'graph' library from boost to work, and if PdfContentsGraph can't see the correct boost library ('graph') then would I get the error 'PdfContentsGraph' was not declared in this scope' ?

I'll post all the code for my main. module below. When I hover the mouse over the line 86, a small popup window recognises 'PdfContentsGraph' as a Class. It shows it as..
Class PdfContentsGrapt (....) So it can be seen and is clearly declared in the header on the second line line .

I just can't imagine what it's missing.

    #include "podofo.h"
    #include "PdfContentsGraph.h"


    #include <iostream>
    #include <stack>
    #include <algorithm>
    #include <string>
    #include <iomanip>
    #include <cstdio>

    using namespace std;
    using namespace PoDoFo;


    void usage()
    {
        printf("Usage: pdfcontentgraph [-a] input_filename\n");
        printf("       -a   Process all pages of input, not just first\n");
    }

    int main( int argc, char* argv[] )
    {
        bool all_pages = false;
        int firstPageNo = 0;
        string inputFileName;
        ++argv;
        --argc;
        while (argc)
        {
            if( argv[0][0] == '-' )
            {
                // Single character flag
                switch( argv[0][1] )
                {
                    case 'a':
                        // Process all pages, not just first page
                        all_pages = true;
                        break;
                    default:
                        usage();
                        return 1;
                }
            }
            else
            {
                // Input filename
                if (inputFileName.empty())
                {
                    inputFileName = argv[0];
                }
                else
                {
                    usage();
                    return 1;
                }
            }
            ++argv;
            --argc;
        }

        if (inputFileName.empty())
        {
            usage();
            return 1;
        }

        try
        {
            PdfMemDocument doc( inputFileName.c_str() );
            if( !doc.GetPageCount() )
            {
                std::cerr << "This document contains no page!" << std::endl;
                return 1;
            }

            int toPage = all_pages ? doc.GetPageCount() : firstPageNo + 1 ;
            for ( int i = firstPageNo; i < toPage; ++i )
            {
                cout << "Processing page " << setw(6) << (i+1) << "..." << std::flush;
                PdfPage* page = doc.GetPage( i );
                PODOFO_RAISE_LOGIC_IF( !page, "Got null page pointer within valid page range" );

                PdfContentsTokenizer tokenizer( page );
  **Line 86**       PdfContentsGraph grapher( tokenizer );

                cout << " - page ok" << endl;
            }
        }
        catch( const PdfError & e )
        {
            e.PrintErrorMsg();
            return e.GetError();
        }

        cout << endl;
        return 0;
    }

Edited 4 Years Ago by daino

Try telling PoDoFo that you have the boost libraries. Add this line to the very start of your code (before including the podofo headers):

#define PODOFO_HAVE_BOOST

Thanks Mike.. You know what. That did it so thanks for the help. I've spent whole days and nights trying to get this to work.
I couldn't see why this wouldn't work initially but here's my spin on why. Just for anyone else who comes accross this.

When I built PODOFO after building boost. PODOFO CmakeLists file incorporated this mini program 'PdfContentsGraph' and built it when it built the PODOFO library. So all along I have had a working version of PdfContentsGraph which would only build if I had Boost set up as a dependency when building PODOFO.

So, because PdfContentsGraph (this mini program) was built as part of the whole build process of PODOFO, the PODOFO_HAVE_BOOST macro is in the CmakeLists text file which is probably why it doesn't need it at the top of 'main' for the PdfContentsGraph program.

So when I did include #define PODOFO_HAVE_BOOST in main, I'm assuming it only needed this because it is now not being built as part of the whole build process for PODOFO, and so there was therefore nothing indicating that the boost library is available.

My only question now is this: Why would I need to tell PODOFO that I have_boost when I don't do this for all the other dependencies for podofo such as zlib, libpng, libjpeg etc?
Is it because Boost is an external library and not a functioning program? Do I have to include a macro like this whenever I use and external library?

Thanks

All I did is look-up the file "PdfContentsGraph.h" and ended up on this page. Then, I noticed the following line near the top of the header file:

#if defined(PODOFO_HAVE_BOOST)

And then, I wrote the post suggesting to add #define PODOFO_HAVE_BOOST. There's nothing magical about it. Are you saying that you spent "whole days and nights" trying to solve this problem about a class declared in the header file "PdfContentsGraph.h", and it never occurred to you to have a look at the code in that header file? That should have been the first place to look.

So, because PdfContentsGraph (this mini program) was built as part of the whole build process of PODOFO, the PODOFO_HAVE_BOOST macro is in the CmakeLists text file which is probably why it doesn't need it at the top of 'main' for the PdfContentsGraph program.

That makes sense. Another way is to just add PODOFO_HAVE_BOOST as a define in your own building options (in CodeBlocks or whatever else). Or, in command-line, you add -DPODOFO_HAVE_BOOST to the compilation command.

Why would I need to tell PODOFO that I have_boost when I don't do this for all the other dependencies for podofo such as zlib, libpng, libjpeg etc?

It's not unusual to have to do this kind of thing when there are optional dependencies (or dependencies that once were optional). Some libraries even do that for required dependencies too.

Is it because Boost is an external library and not a functioning program? Do I have to include a macro like this whenever I use and external library?

No and no. It is purely a choice by the people who wrote the PoDoFo library. It is reasonably common to have a small set of defines for conditional compilations. A compiler cannot, in general, figure out what are all the available external libraries on your system, so that cannot be tested within the code. The only alternative is to use a build-system (like cmake) that can be used to check for the presence of specific external libraries and consequently set the corresponding defines that will turn on or off the specific parts of the code that relies on those external libraries.

Generally, as a library developer, the choice is to either make the external library a required dependency, in which case you just use it anywhere in your library. Or, make the external library optional (e.g., for certain additional capabilities, or faster alternative for particular algorithms), in which case you have to protect any use of that library by a conditional compilation, exactly as it is done in the "PdfContentsGraph.h" header file. In that case, some external configuration is required set the defines that control those conditional compilations. Setting the defines to turn on the use of some external libraries can be done either directly in the code (before including the headers of that external library), as part of the build-script (e.g., in the cmake files), or directly when calling the compiler in command-line (e.g., -DPODOFO_HAVE_BOOST).

Any given library should have documentation telling you what defines it has, what they mean, and when / how to turn them on. The PoDoFo library is not a good example in that regard, don't generalize. The world of open-source libraries is very diverse, and many libraries are particularly horrible in terms of being able to re-build them from source on your own system, or in terms of documentation and build configurations in general. That is partly why I love Linux (where these issues are fewer and much easier to resolve), and why I tend to try and stay away from dubious open-source libraries, especially if I only need a small part of it.

Are you saying that you spent "whole days and nights" trying to solve this problem about a class declared in the header file "PdfContentsGraph.h", and it never occurred to you to have a look at the code in that header file? That should have been the first place to look.

Well, anyone following this trail should be able to build PODOFO on Windows now.
When I ran Cmake to crate a Makefile (after building boost), I added a flag to the command line -DWANT_BOOST:BOOL=1, so in my own confused way I thought this had been taken care of and the podofo library would therefore built in such a way which would make Boost visible to PODOFO. Clearly it wasn't.
Anyway, I understand now. Cheers.

This question has already been answered. Start a new discussion instead.