wlav / cppyy

Other
387 stars 39 forks source link

failed to convert long double pointer argument #155

Closed myusernameisunique closed 8 months ago

myusernameisunique commented 1 year ago

I am able to create an array of int, bool, float, and double and successfully pass them to a custom c function using cppyy, but when I try the same with long double, it fails and I get the following output:

123
Traceback (most recent call last):
  File "............/repro.py", line 12, in <module>
    print(cppyy.gbl.passingLongDouble(bar))
TypeError: int ::passingLongDouble(long double* bar) =>
    TypeError: could not convert argument 1 (could not convert argument to buffer or nullptr)

Here is the python code I used:

import cppyy
from ctypes import c_double, c_longdouble

# DOES work
cppyy.cppdef("""int passingDouble(double * foo) { return 123; }""")
foo = (c_double * 2)()
print(cppyy.gbl.passingDouble(foo))

# DOES NOT work
cppyy.cppdef("""int passingLongDouble(long double * bar) { return 456; }""")
bar = (c_longdouble * 2)()
print(cppyy.gbl.passingLongDouble(bar))

I ran the python script in 2 different environments and both yield the same result. Here they are:

python == 3.9.7
cppyy == 2.4.2
ctypes == 1.1.0
python == 3.10.11
cppyy == 3.0.0
ctypes == 1.1.0
wlav commented 1 year ago

long double pointer per se works:

from ctypes import c_double, c_longdouble, POINTER
...
bar = POINTER(c_longdouble)()

So I presume that it's the array conversion, rather than pointer conversion that's the issue. (Historically, long double was left out there, b/c Python's module array does not support long double.)

wlav commented 1 year ago

Yes, long double apparently uses a format code of g, whereas cppyy is expecting D. Is fixed in repo.

wlav commented 8 months ago

Released with release 3.1.0. Feel free to reopen if you continue to have issues.