Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
How to pass "const float *" list to an objc function?
-
So this is only tangentially pythonista-related, but I encountered it recently while trying to do some objective-c drawing via CGContext function calls, which required a deeper understanding of calling raw functions from python.
One of the functions I wanted to call was this one:
CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, CFArrayRef colors, const CGFloat *locations);
So I defined the ctypes function call like this:
c_float_p = ctypes.POINTER(ctypes.c_float) CGGradientCreateWithColors = objc_util.c.CGGradientCreateWithColors CGGradientCreateWithColors.restype = c_void_p CGGradientCreateWithColors.argtypes = [c_void_p, c_void_p, c_float_p]
Which seemed to match the required types.
Then I tried to call it using this setup:locations = (ctypes.c_float * 2)(0.0,1.0) gradient = CGGradientCreateWithColors(colorSpace, objc_util.ns(colors), ctypes.cast(locations, c_float_p))
and while it doesn't crash, it doesn't seem to be getting the location float values correctly within objc. The result is a gradient with the right colors, but with the wrong interpolation. But I can't find the right way to give the float * array of values to it so that it interprets them properly. So, perhaps someone with better knowledge will be able to point to what I'm doing wrong, either in my definition of the argtypes or in how I generate the values to send. Is it, perhaps that CGFloat is not compatible with c_float?
-
@shinyformica see a topic explaining
-
@cvp yep...just realized that must be the reason, since CGFloat can be 32 or 64 bits, so isn't always compatible with a float.
I just changed things to this:CGFloat_p = ctypes.POINTER(objc_util.CGFloat) CGGradientCreateWithColors = objc_util.c.CGGradientCreateWithColors CGGradientCreateWithColors.restype = c_void_p CGGradientCreateWithColors.argtypes = [c_void_p, c_void_p, CGFloat_p] locations = (objc_util.CGFloat * 2)(0.0,1.0) gradient = CGGradientCreateWithColors(colorSpace, objc_util.ns(colors), ctypes.cast(locations, CGFloat_p))
and of course it works fine now. Should have realized that right away. I'll update the original thread as well.