Skip to main content
GameDev.net gamedev.net
🔒 Locked

[PYTHON] C++ pointers are a pain...

Started by c0d360d Oct 19, 2007 at 12:28 PM 8 replies 1.7k views
Original Post
c0d360d
c0d360d
Building on the previous project click here for reference I've recoded the test1.cpp once again, and it worked perfectly. new test1.cpp on pastebin Then I added the code for HAPI_AllegroCreateBitmap, and now it dies with a segmentation fault. The code that I used is somewhat of a rip from the PyGame sources. I'm not fully certain what it does (I know, I know, never use code that you don't know what it does..I know.), and I'm trying hard to figure it out. This is all a learning experience, and if the Python docs were clear enough for me to understand how this stuff worked, I'd be in better shape. But I'm afraid that after reading the docs over and over, I still cannot make enough sense of the advanced features of extending/embedding to do what I want. I decided to look into the source to Pygame to see how they handle the bitmaps, and so I tried to do the same thing.. sorta. What I expected of the code is the pointer address of an allegro BITMAP to be printed out. Perhaps I am misinterpreting all of this. Any help is greatly appreciated. I know that the problem lies in this code:

int w, h;
PyArg_ParseTuple (pParams, "ii", &w, &h);
BITMAP * test_bmp = create_bitmap (w, h);
	
#define PyObject_FromBitmap (*(PyObject*(*)(BITMAP*))(void**)PyCObject_AsVoidPtr(PyDict_GetItemString(g_pkHost->m_ptScript->m_pkModuleDictionary, "CreateBitmap")))

return PyObject_FromBitmap (test_bmp);

But I have no clue what I need to do to get the results that I want. Terminal execution result:

$ ./HOSTOne 
Segmentation fault (core dumped)
script.py

import HostAPI
from Allegro.KeyDefs import *

class Data: pass

def Init():
	
	Data.SCREEN_WIDTH 	= 800
	Data.SCREEN_HEIGHT 	= 600
	Data.SCREEN_DEPTH 	= 16
	Data.FULLSCREEN		= 0

	HostAPI.SetVideoMode(Data.SCREEN_WIDTH, Data.SCREEN_HEIGHT, Data.SCREEN_DEPTH, Data.FULLSCREEN)

	# test should print out the allegro BITMAP pointer address I think
	bmpTest = HostAPI.CreateBitmap(128, 128)
	print bmpTest

def HandleFrameInput():
	HostAPI.PollKeyboard()
	
	if HostAPI.KeyPressed(KEY_ESC): HostAPI.StopHOST()

def RenderFrame():
	HostAPI.ClearBuffer()
	
	HostAPI.FlipBuffer()

def HandleFrame():

	print 'Random Number from HOST: ', HostAPI.GetRandomNumber(1, 10)
	
	HandleFrameInput()
	
	RenderFrame()

def Main():
	count = 0
	while True:
		count += 1
		if count >= 65536: break # testing
		HandleFrame()

Palidine
Palidine
1) you're not running it in a debugger: do that. It'll make it 1000% easier to figure out the bugs (they don't call it a debugger for no reason...)

2) that code will crash if: g_pkHost is NULL, m_ptScript is NULL, m_pkModelDictionary is NULL, if the function returns NULL

-me
SiCrane
SiCrane
Give some serious thought to using some binding layer like boost::python instead of all these raw Python C API calls. Doing so can greatly reduce the number of problems like you seem to be having.
c0d360d
c0d360d
Quote:
Original post by Palidine
1) you're not running it in a debugger: do that. It'll make it 1000% easier to figure out the bugs (they don't call it a debugger for no reason...)

2) that code will crash if: g_pkHost is NULL, m_ptScript is NULL, m_pkModelDictionary is NULL, if the function returns NULL

-me


What is a good debugger that runs on the linux platform?
The only debugger I've ever used before was the one that is integrated in the Dev-C++ IDE for windows.

I added some code to check for NULLs...and it still fails.
	if (NULL != g_pkHost)	{		if (NULL != g_pkHost->m_ptScript)		{			if (NULL != g_pkHost->m_ptScript->m_pkModuleDictionary)			{				if (NULL != PyDict_GetItemString (g_pkHost->m_ptScript->m_pkModuleDictionary, "CreateBitmap"))				{					return PyObject_FromBitmap (test_bmp);				}				else				{					fprintf(stderr, "PyDict_GetItemString (g_pkHost->m_ptScript->m_pkModuleDictionary, \"CreateBitmap\") is NULL!\n");					exit(1);				}			}			else			{				fprintf(stderr, "g_pkHost->m_ptScript->m_pkModuleDictionary is NULL!\n");				exit(1);			}		}		else		{			fprintf(stderr, "g_pkHost->m_ptScript is NULL!\n");			exit(1);		}	}	else	{		fprintf(stderr, "g_pkHost is NULL!\n");		exit(1);	}		return PyInt_FromLong(0);

c0d360d
c0d360d
Quote:
Original post by SiCrane
Give some serious thought to using some binding layer like boost::python instead of all these raw Python C API calls. Doing so can greatly reduce the number of problems like you seem to be having.



I really wanted to figure out the hard way how to do this before relying on a third party interface layer.
I will more than likely use boost::python if I try to do a real project.
I know that what I want to do is possible without boost, and so I want to learn how.

Thanks though.
c0d360d
c0d360d
I got more of it figured out.

Terminal:
$ ./HOSTOne DEBUG: HostAPI.CreateBitmap() DEBUG: creating allegro bitmap...DEBUG: bitmap created.DEBUG: g_pkHost is OKDEBUG: g_pkHost->m_ptScript is OKDEBUG: g_pkHost->m_ptScript->m_pkModuleDictionary is OKPyDict_GetItemString (g_pkHost->m_ptScript->m_pkModuleDictionary, "CreateBitmap") is NULL!


The seg fault was because I stupidly tried to create the bitmap in the Init function in script.py!
Allegro is not initialized until AFTER Init is called.

Here is the new script.py
import HostAPIfrom Allegro.KeyDefs import *class Data: passdef Init():		Data.SCREEN_WIDTH 	= 800	Data.SCREEN_HEIGHT 	= 600	Data.SCREEN_DEPTH 	= 16	Data.FULLSCREEN		= 0	HostAPI.SetVideoMode(Data.SCREEN_WIDTH, Data.SCREEN_HEIGHT, Data.SCREEN_DEPTH, Data.FULLSCREEN)def HandleFrameInput():	HostAPI.PollKeyboard()		if HostAPI.KeyPressed(KEY_ESC): HostAPI.StopHOST()def RenderFrame():	HostAPI.ClearBuffer()		HostAPI.FlipBuffer()def HandleFrame():	print 'Random Number from HOST: ', HostAPI.GetRandomNumber(1, 10)		HandleFrameInput()		RenderFrame()def Main():		# test should print out the allegro BITMAP pointer address I think	bmpTest = HostAPI.CreateBitmap(128, 128)	print bmpTest		count = 0	while True:		count += 1		if count >= 65536: break # testing		HandleFrame()


and the new HAPI_AllegroCreateBitmap in test.cpp
	fprintf(stderr, "DEBUG: HostAPI.CreateBitmap() \n");	int w, h;	PyArg_ParseTuple (pParams, "ii", &w, &h);	fprintf(stderr, "DEBUG: creating allegro bitmap...\n");	BITMAP * test_bmp = create_bitmap (w, h);	if (NULL != test_bmp)	{		fprintf(stderr, "DEBUG: bitmap created.\n");	}	else	{		fprintf(stderr, "DEBUG: could not create the bitmap of size %d x %d\n", w, h);		exit(1);	}		if (NULL != g_pkHost)	{		fprintf(stderr, "DEBUG: g_pkHost is OK\n");		if (NULL != g_pkHost->m_ptScript)		{			fprintf(stderr, "DEBUG: g_pkHost->m_ptScript is OK\n");			if (NULL != g_pkHost->m_ptScript->m_pkModuleDictionary)			{				fprintf(stderr, "DEBUG: g_pkHost->m_ptScript->m_pkModuleDictionary is OK\n");				if (NULL != PyDict_GetItemString (g_pkHost->m_ptScript->m_pkModuleDictionary, "CreateBitmap"))				{					fprintf(stderr, "DEBUG: Trying to return bitmap.\n");					return PyObject_FromBitmap (test_bmp);				}				else				{					fprintf(stderr, "PyDict_GetItemString (g_pkHost->m_ptScript->m_pkModuleDictionary, \"CreateBitmap\") is NULL!\n");					exit(1);				}			}			else			{				fprintf(stderr, "g_pkHost->m_ptScript->m_pkModuleDictionary is NULL!\n");				exit(1);			}		}		else		{			fprintf(stderr, "g_pkHost->m_ptScript is NULL!\n");			exit(1);		}	}	else	{		fprintf(stderr, "g_pkHost is NULL!\n");		exit(1);	}		return PyInt_FromLong(0);


and I think I know what I'm doing wrong.

I'm calling the function that I'm coding..from the function that I am coding!
the script is calling CreateBitmap ... that is HAPI_AllegroCreateBitmap which makes a call to HAPI_AllegroCreateBitmap ...so there is my error!

I'm pretty sure thats it..unless you see something else.
Thanks for the help. I really appreciate it.
Luctus
Luctus
Quote:
Original post by c0d360d
What is a good debugger that runs on the linux platform?
Insight and DDD are two pretty good standalone debuggers. Development environments such as KDevelop, Anjuta and Emacs have their own integrated debugger interfaces.

-LuctusIn the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move - Douglas Adams
c0d360d
c0d360d
Quote:
Original post by Luctus
Quote:
Original post by c0d360d
What is a good debugger that runs on the linux platform?
Insight and DDD are two pretty good standalone debuggers. Development environments such as KDevelop, Anjuta and Emacs have their own integrated debugger interfaces.


I installed DDD.
I like it.
Thanks that should help. :)
doctorsixstring
doctorsixstring
Quote:
Original post by c0d360d
I really wanted to figure out the hard way how to do this before relying on a third party interface layer.


What do you have against third party tools? You're using Python, so I can only assume you're not a total masochist. Will your game be more fun because you're avoiding Boost (and similar tools like SWIG or Pyrex)? Will learning the guts of the extension API help you get a job? The answer to both is no, so why not devote your time to more exciting endeavors?

- Mike
smr
smr
Quote:
Original post by SiCrane
Give some serious thought to using some binding layer like boost::python instead of all these raw Python C API calls. Doing so can greatly reduce the number of problems like you seem to be having.


Or the ctypes module. It's a standard module beginning with python 2.5.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.