strange issue with C extension using Py_BuildValue

B

bobicanprogram

I'm am having "strange" problems with the code snip below.

When this code is built on a 64bit Linux, it would appear to work
flawlessly. When the source is rebuilt on a 32bit Linux it begins
to crack in strange ways. The issue seems to be associated with the
sender field in the Py_BuildValue call. The fact that sender is a
pointer should mean that its value is an unsigned integer. However,
on the 32 bit build the failure is that the msgPtr->data value is
"messed up". If the format associated with the sender (a pointer)
from "L" to "i" things work on the 32 bit side but break on the 64 bit
side.

I fully understand that an address will be stored differently on the
64bit vs. the 32bit systems. The problem is that the code is
recompiled from source in both cases so shouldn't the "L" format work
as expected in both architectures? Furthermore, how can an
incorrect format result in messing up the field which follows?

Thanks in advance for any help.

bob
PS.
The Python side using this extension isn't expecting to do anything
with the sender parameter other than store it for later use as a
parameter in a Reply() function call. ie. an address goes from
extension ->Python -> extension.

========= begin code snip ===================
static PyObject *simpl_receive(PyObject *self, PyObject *args)
{
int ret;
char *sender;
FCMSG_REC *msgPtr;

// call the actual simpl C library function
ret = Receive(&sender, NULL, 0);

// what sort of message are we dealing with?
if (ret > 0) // message
{
msgPtr = (FCMSG_REC *)sender;
return( Py_BuildValue("iLz#", ret, sender, &msgPtr->data, ret) );
}

========== end code snip ============
 
M

Mark Hammond

I'm am having "strange" problems with the code snip below.

When this code is built on a 64bit Linux, it would appear to work
flawlessly. When the source is rebuilt on a 32bit Linux it begins
to crack in strange ways. The issue seems to be associated with the
sender field in the Py_BuildValue call. The fact that sender is a
pointer should mean that its value is an unsigned integer. However,
on the 32 bit build the failure is that the msgPtr->data value is
"messed up". If the format associated with the sender (a pointer)
from "L" to "i" things work on the 32 bit side but break on the 64 bit
side.

I expect that in a 32bit build of linux, a "long long" (the 'L' format)
is still 64 bits. You probably want something like:

Py_BuildValue("iNz#", ret, PyLong_FromVoidPtr(sender), &msgPtr->data, ret);

and PyLong_AsVoidPtr() for the other direction.

HTH,

Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,058
Latest member
QQXCharlot

Latest Threads

Top