EggData access in C++/EggParsing help!

Hi all,

Here is the problem:

I have a model of a plane which has 4x4 subdivisions and I would like to read the faces (by this I mean get access to each vertex of a face) in order (say from the bottom left to the top right) from the egg file made in Blender.

I researched through the forums and found the egg parsing classes EggData, EggGroupNode etc but I am not able to figure out how to use them for my purposes.

Also, I did a test with EggData:


void egg_parser(const char* egg_file_name) {
	assert(egg_file_name && "File Name Error");
	EggData *egg = new EggData();
	Filename file(egg_file_name);
	egg->resolve_egg_filename(file);
	egg->read(file);
}

But this bugs out saying:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

Any help ?

Seems like you did everything right, with the exception that it should be:

PT(EggData) egg = new EggData();

instead of:

EggData *egg = new EggData();

because EggData inherits from ReferenceCount, and thus should always be stored in a PT(EggData) instead of a plain pointer.

But I doubt this is causing your crash. It sounds instead like some fundamental problem with your compilation environment, e.g. mismatched libraries, or mismatched compilers. As the error message says, you appear to be experiencing two different calling conventions here, which shouldn’t be possible unless you have mixing-and-matching C++ code for two different ABI’s.

Do other C++ programs work in your compilation environment? If so, did your libpandaegg.dll file come from the same environment?

Can you run the same code at the Python level without crashing?

David

I replaced the PT() but no change in compilation.

I also, noticed that if I comment out the line :

//egg->read(file);

the error doesn’t exist.

I did try the same code in python and it compiles fine.

I am using Visual Studio 2008 Express Edition in Windows Vista, if that has anything to do with it.

Also, other C++ panda programs work fine in this environment. The libpandaegg.dll is linked the same way as the other dll’s and is from the same environment.

Well, the fact that it works in Python proves that it is, indeed, something broken with your compilation or runtime linking environment in C++.

Perhaps if you got a stack trace from the debugger at the point of the failure, it might give you more information as to what, precisely, is going wrong?

David

I did a stack trace but wasn’t able to get any useful information. Is there something in particular I should be looking for ?

Also, I did some step by step debugging and I noticed that it steps past the final statement (egg->read(file)) and gives the run time error at the end of the function.

I did some reading on forums and they say it could be :

because of the dll being compatible with __cdecl and not __stdcall calling conventions (which is for windows) but this sounds weird, since why would libpandaegg.lib cause this error and not others.

I will keep experimenting and hope something fixes it.

Did you mean the assembly code produced by the debugger ?

If so, here is the assembly for after it crashed that I could get out of it…from the read function.

Just for a recap:

void egg_parser(const char* egg_file_name) {
	assert(egg_file_name && "File Name Error");
	PT(EggData) egg1 = new EggData();
	file = new Filename(egg_file_name);
	egg1->resolve_egg_filename(*file);
	egg1->read(*file, "blah");
}

Assembly:


00E6481C  call        @ILT+2265(__RTC_CheckEsp) (0E518DEh)  
	egg1->read(*file, "blah");
00E64821  sub         esp,20h  
00E64824  mov         ecx,esp  
00E64826  mov         dword ptr [ebp-0ECh],esp  
00E6482C  push        offset string "blah" (0E6FF3Ch)  
00E64831  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (0E51AE6h)  
00E64836  mov         dword ptr [ebp-140h],eax  
00E6483C  mov         eax,dword ptr [ebp-140h]  
00E64842  mov         dword ptr [ebp-144h],eax  
00E64848  mov         byte ptr [ebp-4],4  
00E6484C  sub         esp,3Ch  
00E6484F  mov         ecx,esp  
00E64851  mov         dword ptr [ebp-0E0h],esp  
00E64857  mov         esi,esp  
00E64859  mov         edx,dword ptr [file (0E744CCh)]  
00E6485F  push        edx  
00E64860  call        dword ptr [__imp_Filename::Filename (0E75978h)]  
00E64866  cmp         esi,esp  
00E64868  call        @ILT+2265(__RTC_CheckEsp) (0E518DEh)  
00E6486D  mov         dword ptr [ebp-148h],eax  
00E64873  mov         eax,dword ptr [ebp-148h]  
00E64879  mov         dword ptr [ebp-14Ch],eax  
00E6487F  mov         byte ptr [ebp-4],5  
00E64883  lea         ecx,[ebp-14h]  
00E64886  call        PointerTo<EggData>::operator-> (0E5121Ch)  
00E6488B  mov         byte ptr [ebp-4],1  
00E6488F  mov         ecx,eax  
00E64891  call        dword ptr [__imp_EggData::read (0E75A28h)]  
}
00E64897  mov         dword ptr [ebp-4],0FFFFFFFFh  
00E6489E  lea         ecx,[ebp-14h]  
00E648A1  call        PointerTo<EggData>::~PointerTo<EggData> (0E514FBh)  
00E648A6  push        edx  
00E648A7  mov         ecx,ebp  
00E648A9  push        eax  
00E648AA  lea         edx,[ (0E648D8h)]  
00E648B0  call        @ILT+915(@_RTC_CheckStackVars@8) (0E51398h)  
00E648B5  pop         eax  
00E648B6  pop         edx  
00E648B7  mov         ecx,dword ptr [ebp-0Ch]  
00E648BA  mov         dword ptr fs:[0],ecx  
00E648C1  pop         ecx  
00E648C2  pop         edi  
00E648C3  pop         esi  
00E648C4  pop         ebx  
00E648C5  add         esp,14Ch  
00E648CB  cmp         ebp,esp  
00E648CD  call        @ILT+2265(__RTC_CheckEsp) (0E518DEh)  
00E648D2  mov         esp,ebp  

The debugger points to the last statement in this assembly code on the crash.

Also, when I step through debug in Visual Studio, I am unable to enter either the EggData or Filename functions. Is this normal ?

From my normal c++ linker additions for Panda3d, the only new thing I have done is added libpandaegg.lib to the linker settings.

Is something missing ?

Well, this just confirms the original report: the MSVS runtime is complaining because something in the egg->read() call has mucked with an important register inappropriately.

This still sounds like something is different between the way that libpandaegg was compiled, and the way your application was compiled. Maybe a different debug/release setting, maybe a different runtime library setting, maybe a different threads setting, maybe a different NDEBUG setting, maybe a different version of the compiler; any of these could cause this sort of error.

Are you absolutely sure that you have the same compilation settings in both cases?

David

I made some progress.

I fixed this but am not sure why it got fixed.

I changed the include directory to the built/bin and so libpandaegg.dll was accessed from there now. This somehow allowed the MSVS debugger to step through into EggData.cpp and show me line by line.

It seems to execute the read function correctly but still bugs out on exiting it.

For the compilation settings that you asked me to check,

I checked it with the solution file I used to build panda and with my previous successful C++ panda solutions :

  1. Different Debug/Release settings

I use the same configuration for both.

  1. Different runtime library setting

The only runtime library settings I use are changing the linker dependencies to include :

libp3framework.lib;
libpanda.lib;
libpandafx.lib;
libpandaexpress.lib;
libp3dtool.lib;
libp3dtoolconfig.lib;
libp3pystub.lib;
libp3direct.lib;
libpandaode.lib;
libpandaegg.lib

  1. Different thread settings

I tried all the 4 options but still bugs out:

MultiThreaded (/MT)
MultiThreaded Debug (/MTd)
MultiThreaded DLL (/MD)
MultiThreaded Debug DLL (/MDd)

  1. Different NDEBUG setting

I haven’t used these in my code anywhere. I don’t really understand it but I read here that this is related to what I was doing in step 3 ? - stackoverflow.com/questions/2290 … -vs-ndebug.

  1. Different version of compiler

Nope. It is the same VS2008 Express or VS2010 (other programs work for both).