Bugs item #1575945, was opened at 2006-10-12 16:25
Message generated for change (Comment added) made by theller
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1575945&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Python Library
Group: None
>Status: Closed
>Resolution: Works For Me
Priority: 5
Submitted By: Albert Strasheim (albertstrasheim)
Assigned to: Thomas Heller (theller)
Summary: from_param and _as_parameter_ truncating 64-bit value

Initial Comment:
There seems to be something strange going on with
ctypes' _as_parameter_ on 64-bit machines. I haven't
been able to replicate this problem without NumPy, but
it looks like a ctypes issue since NumPy's
_as_parameter_ contains a valid value but the value
that arrives in the C function has had its upper 4
bytes zeroed.

SConstruct to build library:

env = Environment()
env.Replace(CCFLAGS=['-O0','-ggdb','-Wall','-ansi','-pedantic'])
env.SharedLibrary('spfuncs',['spfuncs.c'])

C code:

#include <stdio.h>
void nnz(double *ary) {
    printf("ary = %p\n", (void*)ary);
}

Python code:

import numpy as N
from ctypes import *
from numpy.ctypeslib import ndpointer
_libspfuncs = N.ctypeslib.load_library('libspfuncs',
__file__) _libspfuncs.nnz.restype  = None A =
N.eye((128)) print 'data_as',
A.ctypes.data_as(c_void_p) print 'array interface',
hex(A.__array_interface__['data'][0])
_libspfuncs.nnz.argtypes = [POINTER(c_double)]
_libspfuncs.nnz(A.ctypes.data_as(POINTER(c_double)))
_libspfuncs.nnz.argtypes = [ndpointer(dtype = N.float64)]
_libspfuncs.nnz(A)
print '_as_parameter', hex(A.ctypes._as_parameter_)

Output on 32-bit system:

data_as c_void_p(-1212006392)
array interface -0x483dbff8
ary = 0xb7c24008
ary = 0xb7c24008
_as_parameter -0x483dbff8

Output on 64-bit system:

data_as c_void_p(46912559644688)
array interface 0x2aaaae740010
ary = 0x2aaaae740010
ary = 0xae740010
_as_parameter 0x2aaaae740010

----------------------------------------------------------------------

>Comment By: Thomas Heller (theller)
Date: 2006-10-19 19:17

Message:
Logged In: YES 
user_id=11105

This is a ctypes 1.0.0 bug then ;-).

Python 2.5 contains ctypes 1.0.1, which is not yet released
as standalone package, but I'll do it ASAP.

Therefore I'll close this report as 'works for me', please
reopen if it still does not work with Python 2.4 and ctypes
1.0.1.

----------------------------------------------------------------------

Comment By: Stefan van der Walt (sjvdw)
Date: 2006-10-18 03:40

Message:
Logged In: YES 
user_id=1104792

On both 32 and 64-bit systems, running param.py under python
2.4 with ctypes 1.0.0 and numpy from SVN (with patch
applied) I see:

$ python param.py 
(-1264099320, False)
Traceback (most recent call last):
  File "param.py", line 16, in ?
    print hex(func(A))
ctypes.ArgumentError: argument 1: exceptions.TypeError:
Don't know how to convert parameter 1



----------------------------------------------------------------------

Comment By: Thomas Heller (theller)
Date: 2006-10-17 19:48

Message:
Logged In: YES 
user_id=11105

I replaced in numpy/core/_internal.py, version 1.0rc2, the
get_as_parameter method with this code:

    def get_as_parameter(self):
        ##return self._data
        return self._ctypes.c_void_p(self._data)

and here is the script and the output on a 64-bit Linux
system, with Python 2.5:

[EMAIL PROTECTED]:~/devel/release25-maint$ cat param.py
import numpy
from numpy.ctypeslib import ndpointer
from ctypes import *
import _ctypes_test

A = numpy.eye(1280)

print A.__array_interface__['data'],
hex(A.__array_interface__['data'][0])

func = CDLL(_ctypes_test.__file__)._testfunc_p_p
func.restype = c_void_p
func.argtypes = [ndpointer(dtype=numpy.float64)]

print hex(func(A))
[EMAIL PROTECTED]:~/devel/release25-maint$ ./python param.py
(46912527945744, False) 0x2aaaac905010
0x2aaaac905010
[EMAIL PROTECTED]:~/devel/release25-maint$


As you can see the 64-bit pointer is passed through the
function.  _testfunc_p_p in _ctypes_test.so is simply

char * _testfunc_p_p (void *s)
{
    return (char *)s;
}


----------------------------------------------------------------------

Comment By: Albert Strasheim (albertstrasheim)
Date: 2006-10-16 18:18

Message:
Logged In: YES 
user_id=945096

Changing NumPy's _as_parameter_ to return the pointer as a
c_void_p causes ctypes to raise the following erorr:

ctypes.ArgumentError: argument 1: exceptions.TypeError:
Don't know how to convert parameter 1

----------------------------------------------------------------------

Comment By: Thomas Heller (theller)
Date: 2006-10-16 17:05

Message:
Logged In: YES 
user_id=11105

This is not a ctypes bug.

It seems that A.ctypes._as_parameter_ is a Python integer. 
These are passed as 'C int' type to foreign function calls.
(The C int type typically has 32 bits on 64-bit platforms,
while a pointer has 64 bit.)

To pass a pointer, A.ctypes._as_parameter_ should be a
ctypes c_void_p instance, not a Python integer.

----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2006-10-14 22:07

Message:
Logged In: YES 
user_id=21627

Thomas, can you take a look? If not, please unassign.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1575945&group_id=5470
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to