im trying my hand at calling c functions from python. im reading up the tutorial http://csl.sublevel3.org/C-functions-from-Python/. however part of the tutorial says that i should

Compiling dynamic libraries on Mac OS X is different from the usual gcc -shared you might be used to:

gcc -dynamiclib -I/usr/include/python2.3/ -lpython2.3 -o myModule.dylib myModule.c

i am not sure how to do this. ive tried typing that under
"add the following commands when calling compiler" under compiler options but it did not work

any help please?

wrong forum thread im sorry this should have been under c. i cant find delete though

I was playing with this a while ago...quite a while ago so I can't guarantee that any of this code will work..

Here's the code that I used.

mywrap.c

#include <Python.h>

extern int intlimit(int);
extern int glblimit(int);
extern void* intbase(unsigned long);
extern void* glbbase(unsigned long);
extern unsigned long myfunc(void*);

PyObject *testex_myfunc(PyObject *self, PyObject *args)
{
	void* val;
	PyObject *MyObj;
	unsigned long ans;
		
	if (!PyArg_ParseTuple(args, "O", &MyObj))
	{
		return NULL;	
	}
	
	val = PyLong_AsVoidPtr(MyObj);	
	
	ans = myfunc(val);
		
	return Py_BuildValue("l", ans);
}


PyObject *testex_glbbase(PyObject *self, PyObject *args)
{
	void* ans;
	unsigned long val;
	
	if (!PyArg_ParseTuple(args, "l", &val))
	{
		return NULL;	
	}
	
	ans = PyLong_FromVoidPtr(glbbase(val));
	
	return Py_BuildValue("O", ans);
}

PyObject *testex_intbase(PyObject *self, PyObject *args)
{
	void* ans;
	unsigned long val;
	
	if (!PyArg_ParseTuple(args, "l", &val))
	{
		return NULL;	
	}
	
	ans = PyLong_FromVoidPtr(intbase(val));
	
	return Py_BuildValue("O", ans);
}


PyObject *testex_intlimit(PyObject *self, PyObject *args)
{
	int ans, val;
	
	if (!PyArg_ParseTuple(args, "i", &val))
	{
		return NULL;	
	}
	
	ans = intlimit(val);
	
	return Py_BuildValue("i", ans);
}

PyObject *testex_glblimit(PyObject *self, PyObject *args)
{
	int ans, val;
	
	if (!PyArg_ParseTuple(args, "i", &val))
	{
		return NULL;	
	}
	
	ans = glblimit(val);
	
	return Py_BuildValue("i", ans);
}


static PyMethodDef testexmethods[] = 
{
	{"intlimit", testex_intlimit, METH_VARARGS,"return interrupt table limit"},
	{"glblimit", testex_glblimit, METH_VARARGS,"return global table limit"},
	{"intbase", testex_intbase, METH_VARARGS,"return interrupt base address"},
	{"glbbase", testex_glbbase, METH_VARARGS,"return global base address"},
	{"myfunc",testex_myfunc,METH_VARARGS,"get pointer value"},
	{NULL,NULL},
};

void inittestex(void)//the name of the module is testex but this function must be called inittestex 
{
	Py_InitModule("testex", testexmethods);
}

test.c

int intlimit(int val)
{
	char ch[(sizeof(unsigned short) + sizeof(void*))];
	
	__asm__ __volatile__
	(
		"sidt	%0\n\t"
		:"=m"(ch)	
	);			
	return *(unsigned short*)ch;	
}

int glblimit(int val)
{
	char ch[(sizeof(unsigned short) + sizeof(void*))];
	
	__asm__ __volatile__
	(
		"sgdt	%0\n\t"
		:"=m"(ch)	
	);
	return *(unsigned short*)ch;		
}

void* intbase(unsigned long val)
{
	char ch[(sizeof(unsigned short) + sizeof(void*))];
	__asm__ __volatile__
	(
		"sidt	%0\n\t"
		:"=m"(ch)	
	);
	
	return *(void**)&ch[2];	
}

void* glbbase(unsigned long val)
{
	char ch[(sizeof(unsigned short) + sizeof(void*))];
	__asm__ __volatile__
	(
		"sgdt	%0\n\t"
		:"=m"(ch)	
	);
	
	return *(void**)&ch[2]; 
}

unsigned long myfunc(void *vptr)
{
	return *(unsigned long*)vptr;	
}

Readme

to compile

gcc -fPIC -c test.c
gcc -fPIC -c -I/usr/include/python2.6 mywrap.c
gcc -shared test.o mywrap.o -o testex.so

in Python

import testex
testex.intlimit(4)
testex.glblimit(4)
hex(testex.intbase(6))
hex(textex.glbbase(8))

*****remember...the functions are called from and response to Python
*****Meaning they are created with C and have C variables
*****but have to convert any variables to Python equivalent
*****i.e
*****void* intbase(int val)
*****you have to convert the return value of intbase with
*****ans = PyLong_FromVoidPtr(intbase(val));
*****
*****for C parameters
*****unsigned long myfunc(void* vptr)
*****you must use a Python type
*****like val = PyLong_AsVoidPtr(MyObj);
*****ans = myfunc(val);
*****	if (!PyArg_ParseTuple(args, "O", &MyObj))
*****	{
*****		return NULL;	
*****	}

Just tried the above code and it works on my machine. Note since I used inline asm in my functions it may fail on your machine.

Edited 5 Years Ago by gerard4143: n/a

This article has been dead for over six months. Start a new discussion instead.