[Tutorial]:Quick and dirty, compile pview.cxx in VS 2003

I spent quite a bit of time searching on the forums and in the manual for simple step-by-step instructions for compiling a simple c++ app in visual studio that links against panda without having to rebuild everything.

I finally found what I needed buried in the following topics:

post from zpavlov

post from Josh Yelon

While I was searching I noticed a lot of people seem interested in this topic. Here, I’d like to record my experience starting from scratch in the hope that it will help future panda3d c++ developers.

ASSUMPTIONS:
In which I outline all of the prepatory steps you should take to before embarking.

1.) You should have panda 3d installed via the regular panda3d install package. (The version I am using is: Panda3D-1.2.3).

2.) You should have the source code to pview.cxx. This is a simple model viewer app that comes w/panda. It also seems to be the best example of a pure C++ app that uses panda3d.

You can get pview.cxx from the full downloadable source distribution of panda or from part 1 of the 3 part distribution or you can cvs it from sourceforge. I recommend the full source distribution becasue it contains the “third party” libs that you’ll also need for this tutorial.

You’ll find pview.cxx in the main panda source path: “panda\src\testbed\pview.cxx”

3.) You should have the panda3d third party libs. You can get these from the full source distribution of panda or from part 2 of the 3 part distribution. I put these files in my panda installation directory as “C:\Panda3D-1.2.3\thirdparty”. I’m going to assume you did the same for the rest of this tutorial.

TUTORIAL:
You should now have everything you need to get started.

a.) Launch VS 2003 and start a new project.

I made my project a standard win32 console application and started an “empty project”.

b.) Add pview.cxx to your project

I just copied it to my project folder and then added it to the project the usual way.

c.) Setup your path
You can do this in your project properties for each panda project:

For include files go to:
Project>Properties>C++>General>Additional Include Directories

and add: “C:\Panda3D-1.2.3\include”
and “C:\Panda3D-1.2.3\thirdparty\win-libs-vc7\nspr\include”
and “C:\Panda3D-1.2.3\thirdparty\win-python\include”

For libs go to:
Project>Properties>Linker>General>Additional Library Directories

add “C:\Panda3D-1.2.3\lib”
and “C:\Panda3D-1.2.3\thirdparty\win-libs-vc7\nspr\lib”
and “C:\Panda3D-1.2.3\thirdparty\win-python\libs”

or if you’re lazy (I am) put it in your global VS environment path.

Go To: Tools>Options>Projects>VC++ Directories
add the above paths to your Include and Library Directories respectivly

d.)Link to the panda libraries:

under:
Project>Properties>Linker>Input
add:
libpanda.lib libpandaexpress.lib libframework.lib libdtool.lib libdtoolconfig.lib

e.) Compile & Run, you’re DONE !

Just kidding, you’re not done, but you should try it to see what happens. This is how far I got before things got tricky.

Note: I’m compiling in Debug mode by default. Everything below should also work for Release mode. I was able to do both.

Error #1 : Python Debug Library issues

"LINK : fatal error LNK1104: cannot open file 'python24_d.lib'"

Problem: Panda doesn’t come w/the debug lib for python. Neither does the regular python distribution. As far as I can tell you have to go compile all of python in debug mode for the privilege of debugging into python. Not something I cared to do.

Solution: Link agains the release version of Python instead of the debug version.

Go to: Project>Properties>Linker>Input and add “python24_d.lib” to your “Ignore Specific Library” section.

Then add “python24.lib” to your list of “Additional Dependencies”

Kiss your option of debugging into python good bye!

Error #2: Angry Linker

Linking...
pview.obj : error LNK2001: unresolved external symbol "void * (__cdecl* global_operator_new)(unsigned int)" (?global_operator_new@@3P6APAXI@ZA)
pview.obj : error LNK2001: unresolved external symbol "void (__cdecl* global_operator_delete)(void *)" (?global_operator_delete@@3P6AXPAX@ZA)
pview.obj : error LNK2001: unresolved external symbol _gnu_optind
pview.obj : error LNK2001: unresolved external symbol _gnu_optarg

etc…

Problem: Who knows (most likely internal panda stuff)

Solution: Add the preproccesor flag “WIN32_VC”
Go to: Project>Properties>C/C++/Preprocessor and add WIN32_VC to your list of preprocessor directives.

For me this line looks like: WIN32;_DEBUG;_CONSOLE;WIN32_VC

Error #3: Angry Linker Part 2

Linking...
libcpd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __malloc_dbg referenced in function "void * __cdecl operator new(unsigned int,struct std::_DebugHeapTag_t const &,char *,int)" (??2@YAPAXIABU_DebugHeapTag_t@std@@PADH@Z)
libcpd.lib(_tolower.obj) : error LNK2001: unresolved external symbol __malloc_dbg
libcpd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __free_dbg referenced in function "void __cdecl operator delete(void *,struct std::_DebugHeapTag_t const &,char *,int)" (??3@YAXPAXABU_DebugHeapTag_t@std@@PADH@Z)

Problem: Panda apps need to be multithreaded

Solution: Go to: Project>Properties>C/C++>Code Generation and
change “Runtime Library” from “Single-threaded (/ML)” to “Multi-threaded DLL (/MD)”

e.) Compile & Run, you’re DONE FOR REAL!!!

No Really, you’re done. At this point you should have the basic pview app compiled and running in VS using only the libs that come w/the standard panda install and the third party libs provided on the panda site. You should now be able to use pview as a jumping off point for developing full c++ only panda apps using Visual Studio.

Great work on this! It’ll definitely help out with us novices who haven’t had experience with Python (though I am seriously considering looking into it).

I have an issue under VS .NET 2005 that I think others may come across tho that I should pull out and ask for help on:

I have your libs configured as specified in the thread. However, it seems that I am missing some .lib files, namely libframework.lib, libdtool.lib, and libdtoolconfig.lib

I searched the Panda3D directory (I used Panda3D-1.3.2 for this, the most recent version) and could not find the libraries you refer to. I searched the source code directory tree, no dice either.

Here’s the exact message I got after a bunch of precision warnings from Visual C++:

1>Linking…
1>LINK : fatal error LNK1104: cannot open file ‘libframework.lib’
1>Build log was saved at “file://c:\Documents and Settings\userdir\My Documents\dev\visual studio\panda3d\PViewConsole\PViewConsole\Debug\BuildLog.htm”
1>PViewConsole - 1 error(s), 167 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Any ideas?

I haven’t upgraded recently, but I found the libs your looking for in the “lib” directory of my current pada disto (where they should be). So for the version I have , the libs are in “C:\Panda3D-1.3.0\lib”

If you have your paths set up correctly I’m not sure why you’d get this error. My only guess is that you followed my tutorial too closely and didn’t replace the paths to the older version of panda I was using when I wrote the tutorial (good old Panda3d-1.2.3) with the path to your spanking new panda version (looks like it’s Panda3D-1.3.2). So for clarity.

Your include paths should look something like this :

"C:\Panda3D-1.3.2\include" 
"C:\Panda3D-1.3.2\thirdparty\win-libs-vc7\nspr\include" 
"C:\Panda3D-1.3.2\thirdparty\win-python\include" 

And your library paths should be something like this:

"C:\Panda3D-1.3.2\lib" 
"C:\Panda3D-1.3.2\thirdparty\win-libs-vc7\nspr\lib" 
"C:\Panda3D-1.3.2\thirdparty\win-python\libs" 

Unless of course you’ve got panda installed in some wierd path in which case the above paths should be pointing there.

Good Luck!

Turns out the libraries were probably renamed sometime between Panda3D 1.3.0 and 1.3.2 because I was able to compile and link using this as my linker’s input:

libpanda.lib libpandaexpress.lib libp3framework.lib libp3dtool.lib libp3dtoolconfig.lib python24.lib

I had the trouble with the angry linker and your solution also seemed to help to resolve that issue.

Now I’ve run into a two different kinds of errors, one on the Debug build and another on the Release build:

Here’s the build errors for the Release build:

1>Linking…
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle ReferenceCount::_type_handle” (?_type_handle@ReferenceCount@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle Event::_type_handle” (?_type_handle@Event@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol _gnu_optind
1>pview.obj : error LNK2001: unresolved external symbol “private: static class Thread * Thread::_main_thread” (?_main_thread@Thread@@0PAV1@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle TypedWritableReferenceCount::_type_handle” (?_type_handle@TypedWritableReferenceCount@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static void * ObjectDeletor::_global_ptr” (?_global_ptr@ObjectDeletor@@0PAXA)
1>pview.obj : error LNK2001: unresolved external symbol _gnu_optarg
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle PandaNode::_type_handle” (?_type_handle@PandaNode@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle TypeHandle::_none” (?_none@TypeHandle@@0V1@A)
1>pview.obj : error LNK2001: unresolved external symbol “void (__cdecl* global_operator_delete)(void )" (?global_operator_delete@@3P6AXPAX@ZA)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle TextNode::_type_handle” (?_type_handle@TextNode@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol "void * (__cdecl
global_operator_new)(unsigned int)” (?global_operator_new@@3P6APAXI@ZA)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle TextProperties::_type_handle” (?_type_handle@TextProperties@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static int ConfigFlags::_global_modified” (?_global_modified@ConfigFlags@@0HA)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle TextEncoder::_type_handle” (?_type_handle@TextEncoder@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle TypedObject::_type_handle” (?_type_handle@TypedObject@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle TypedWritable::_type_handle” (?_type_handle@TypedWritable@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle NodePathComponent::_type_handle” (?_type_handle@NodePathComponent@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle GraphicsOutput::_type_handle” (?_type_handle@GraphicsOutput@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class TypeHandle TypedReferenceCount::_type_handle” (?_type_handle@TypedReferenceCount@@0VTypeHandle@@A)
1>pview.obj : error LNK2001: unresolved external symbol “private: static class BamCache * BamCache::_global_ptr” (?_global_ptr@BamCache@@0PAV1@A)
1>pview.obj : error LNK2001: unresolved external symbol “public: static class LoaderOptions PandaFramework::_loader_options” (?_loader_options@PandaFramework@@2VLoaderOptions@@A)
1>C:\Documents and Settings\userdir\My Documents\dev\visual studio\panda3d\PViewConsole\Release\PViewConsole.exe : fatal error LNK1120: 22 unresolved externals

The debug build has a completely different type of error, one that happens at run time; according to the console screen:

Warning: unable to auto-locate config files in directory named by “etc”.

The IDE reports an exception and breaks with the call stack:

  • MSVCR71.dll!7c342eee()
  • [Frames below may be incorrect and/or missing, no symbols loaded for MSVCR71.dll]
  • msvcp71.dll!7c3a55ea()
  • msvcp71.dll!7c3a6730()
  • libp3dtoolconfig.dll!006864c9()
  • libp3dtoolconfig.dll!0068a947()
  • msvcp80d.dll!std::_Traits_helper::copy_s<std::char_traits >(char * _First1=0x00000001, unsigned int _Size=6870564, const char * _First2=0x025186f0, unsigned int _Count=4334608) Line 699 + 0x21 bytes C++
  • libp3dtoolconfig.dll!00693eb6()
  • libp3dtoolconfig.dll!00664d33()
  • msvcp80d.dll!std::basic_string<char,std::char_traits,std::allocator >::basic_string<char,std::char_traits,std::allocator >(const char * _Ptr=0x0012ffb8) Line 644 C++
    msvcr80d.dll!_initterm(void (void)* * pfbegin=0x0041e214, void (void)* * pfend=0x0041e39c) Line 855 C
  • PViewConsole.exe!__tmainCRTStartup() Line 501 + 0xf bytes C
  • PViewConsole.exe!mainCRTStartup() Line 403 C
  • kernel32.dll!7d4e992a()

I’m planning to look around the forums a bit for help with these errors, but maybe you’ve run into this before and know what’s happened?

Thanks for the reply. I’ll post again if I find anything.

Well, I compiled mine using VS.Net 2003, it looks like you’re using VS.Net 2005. Without trying it myself I have a feeling your problem lies therin. For example, this part of your dump:

- MSVCR71.dll!7c342eee() 
- [Frames below may be incorrect and/or missing, no symbols loaded for MSVCR71.dll] 
- msvcp71.dll!7c3a55ea() 
- msvcp71.dll!7c3a6730() 

It looks like you’re trying to link agains VS.Net 2003 dlls (Which is VC 7.1, you are compiling w/VC 8.0). As you can probably guess this is a huge problem if you don’t have VC 7.1 installed (incidentally, you can find these dlls in your \bin ).

This problem leads me to a memory I had about going through this process. I belive the reason I chose VS 2003 is that panda seems to like compiling against VC 7.1 better than VC 8.0. In fact there may even be a post that says something that affect or maybe I read it in one of the instruction files for compiling panda from source.

Anyways, the fact that panda comes w/redistributables for VC 7.1 probably means that it was compiled using VC 7.1 and I would bet my money that these problems go away if you switch. Although I would also say that in principle this is a really BAD solution since VC 8 SHOULD be backwards compatible across the board (shame, shame microsoft).

However, if it was me trying to figure it out. I’d try to get it working w/the most friendly environment (VC71) first and then only after that spend some time yanking my hair out and cursing to try and figure out what the difference is between VC71 and VC8.

If you haven’t figured it out after XMass, I may crack this one open again and see if I can offer up anything more concrete than philosophical advice.

Good Luck

Hi,

I’ve just tried to build under VC 2005, too. (I have to because I got no VC 2003.)
The weird thing is I don’t even get to linking. I get a few compile time errors all of which have to do with template cast operator definitions. A representative example looks like:

Error	10	error C2244: 'PointerTo<T>::operator T *' : unable to match function definition to an existing declaration	c:\data\sdks\panda3d-1.3.2\include\pointerto.i	88	

It seems all of the errors are this same kind. Now if you look into pointerTo.h, you’ll find this declaration:

INLINE operator TYPENAME PointerToBase<T>::To *() const;

If you look at the line yielding the error, you’ll find:

template<class T>
INLINE PointerTo<T>::
operator TYPENAME PointerToBase<T>::To *() const {...}

Definition and declaration seem to match just fine. Now PointerToBase::To is really just a typedef to T.
If you change declaration and definition to use just T instead of TYPENAME PointerToBase::To, the error goes away.

Now either my C++ skills are somewhat rusty (possible after 3-4 months pure python) or I’m momentarily blind or something really weird is going on here. Two questions:

  • why use that typedef at all in this situation?
  • why does it make a difference to the compiler?

Can anyone shed light on this? C++ has this habit of surprising me again and again even after more than 10 years working with it, and I hate to stay ignorant :wink:

Many thanks,
Max Hajek
Vienna, Austria

Hmm, now I got the same problem like sanjiyan. I’ll try to find out some information about calling a vc71 linked library from a vc80 linked library because in principle this shouldn’t be a problem.

Cheers,
Max Hajek
Vienna, Austria

Strange, but when I build release it runs just fine. While when building debug, I get about the same crash as sanjiyan.

What I’ll do now is to copy the release config and step by step change its settings to mirror the debug settings till I have the problem again. Once I know more I’ll post it here.
How I hate such stuff…

Cheers,
Max Hajek
Vienna, Austria

One thing about the error with …: You probably have not set your working directory to be \bin, so it cannot find its config.prc file.

Cheers,
Max Hajek
Vienna, Austria

Ok, here’s what you need to do to make it run in debug, too:

a) don’t define _DEBUG, but NDEBUG
b) don’t use Multithreaded Debug Dll Runtime, but Multithreaded Dll Runtime

I do understand why b) (exactly because Panda was probably built with the 71 Multithreaded Dll Runtime), but a) is somewhat unsettling.

Anyway, make these two changes to your debug config, make sure your working directory is set as mentioned in my last post and your custom-vs2005-built pview should run in debug, too, without a problem.

Cheers,
Max Hajek
Vienna, Austria

I added your tutorial to the manual, do you mind?

Here it is:
panda3d.org/manual/index.php/U … ual_Studio

Cool, fame 8)

I tried to compile and run pview.cxx, with following configuration:

Windows VISTA
Panda3D-1.6.2
Python 2.5
MSVC9 (Visual Studio 2008)

Compiling and linking succeeded smoothly, thanks to your precious advice.
But when I run it, I get the following:


panda_viewer.exe - Entry Point Not Found

The procedure entry point ?r_prepare_scene@TextNode@@UAEXPBVRenderState@@PAVPreparedGraphicsObjects@@PAVThread@@@Z could not be located in the dynamic link library libpanda.dll.

OK

This is due to the call to:
framework.get_models().prepare_scene(window->get_graphics_window()->get_gsg());

get_models() will return a NodePath and NodePath::prepare_scene() will call PandaNode::prepare_scene() and finally TextNode::r_prepare_scene()

Anyone knows how I could solve that? I’m currently having problems with a GeomNode in my C++ code wrapped to Python and I would like to demonstrate it on a simple example (pview)

Thanks
-David

In general, if you get an “entry point not found” at runtime, but it built smoothly, it means you have the wrong DLL’s on your path at runtime. You must be inadvertently running with a different libpanda.dll than the one you linked against, maybe another version of Panda that’s installed on your hard disk?

David

You got it!

Now I realize that when running from Python, we have some *.pth file that indicates which Panda3d to use. And I usually always start from Python…

I uninstalled Panda3d-1.5.4 and things are working now.
However I still don’t understand where the system chooses which dll to use at run-time. In my PATH, I actually had both “C:\Panda3D-1.5.4\bin” and “C:\Panda3D-1.6.2\bin”. I tried to remove the older one but I still had the “entry point not found”
Maybe should I have the computer restarted for this to be taken into account? Or at least Visual Studio restarted ?

Anyway uninstalling solved the issue.
Many thanks for your very prompt and efficient reply !

If you’re running from Python, then your PYTHONPATH also contributes to the dll search path. So maybe you still had the old Panda on your PYTHONPATH.

David