omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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 use structures? setting GLKEffectPropertyLight.position, fails

    Pythonista
    4
    18
    10127
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • JonB
      JonB last edited by

      you should be able to cast the result as a POINTER(GLKVector3), then access the .contents().

      I have been working on extending the objc utils to handle union encoding types, though it is not quite working yet (i can generate the structure from the type encoding, but using that as a restype seems to crash.)

      1 Reply Last reply Reply Quote 0
      • Cethric
        Cethric last edited by

        Can you please elaborate on what you mean.
        Using the current OpenGLES repo under GLKit/light.py
        in GLKEffectPropertyLight.getPosition I have tried both setting the return type and argtypes, but neither seem to work.

        def getPosition(self):
                p = GLKVector4()
                self._light.position(ctypes.byref(p), argtypes=[ctypes.POINTER(GLKVector4)], restype=None)
                res = self._light.position(argtypes=[], restype=ctypes.POINTER(GLKVector4))
                print p
                return res.contents
        
        1 Reply Last reply Reply Quote 0
        • JonB
          JonB last edited by

          Something strange seems to be happening in either ctypes, or objc with union return types. At least, on 32 bit, which uses objc_msgSend_stret. That function works by taking in a pointer to an existing structure, and modifying it in place.

          It seems as if the size of the object returned is larger than what is passed in as the restype, causing a crash when the correct structure is used. Oddly, it seems like it does not always crash, for instance sometimes when calling l.position() with no left hand side, i was able to get a result.

          A workaround is to pass in a larger structure for the return type, to ensure nothing gets overwritten. if you want to pass the struct back to objc, however, you must pass the right size, so you can use cast to cast to to correct type. This should work with your Union types as well. You must use the argtypes/restype input to override these.

          from objc_util import *
          
          PropLight = ObjCClass('GLKEffectPropertyLight')  # I will rename it later.
          l = PropLight.alloc().init()
          
          glk4 = parse_struct('{glkvec4=ffff}')
          glk4_union = parse_struct('{glkvec4union=fffff}') #union seems to have an extra field....
          
          # test code:
          newpos=glk4()
          newpos.a=1.
          newpos.b=2.
          newpos.c=3.
          newpos.d=4.
          
          l.setPosition_(newpos,restype=ctypes.c_void_p, argtypes=[glk4])
          
          # read back position, then cast to correct type
          retpos=l.position(restype=glk4_union, argtypes=[])
          pos=ctypes.cast(ctypes.pointer(retpos),ctypes.POINTER(glk4)).contents
          
          print 'original', newpos.a,newpos.b, newpos.c, newpos.d
          print 'returned', retpos.a, retpos.b, retpos.c, retpos.d
          print 'cast', pos.a, pos.b, pos.c, pos.d
          
          1 Reply Last reply Reply Quote 0
          • JonB
            JonB last edited by JonB

            btw, if you are 64 bit, i suspect you can just use position() with restype= GLKVector4 and argtypes=[]. i suspect the extra size trick is needed only for 32 bit. Note you need to use setPosition_ to set.

            1 Reply Last reply Reply Quote 0
            • ccc
              ccc last edited by

              Is it possible that you have discovered an overwrite condition in Apple's API that could be used as an exploit by a dishonest coder?

              1 Reply Last reply Reply Quote 0
              • Cethric
                Cethric last edited by

                @JonB I don't know what you are doing differently to me, but I can't seem to get it to work. (iPad Mini 2, iOS 9.1 (13B5110e))
                @ccc I am not entirely sure what you mean.

                1 Reply Last reply Reply Quote 0
                • JonB
                  JonB last edited by

                  @Cethric. Did my example work for you? If not, what happened?

                  Can you describe your problem more specifically? are you crashing, or just unable to get/set position?

                  @ccc I don't think so. The memory in question is on the heap, and completely nonexecutable.

                  1 Reply Last reply Reply Quote 0
                  • Cethric
                    Cethric last edited by

                    @JonB I am unable to get, I don't not if setting is working either. Using the example you provided I get

                    original 1.0 2.0 3.0 4.0
                    returned 9.45935362045e+19 1.40129846432e-45 2.80259692865e-45 0.0
                    cast 9.45935362045e+19 1.40129846432e-45 2.80259692865e-45 0.0
                    

                    However original, returned and cast should all be the same, shouldn't they?

                    1 Reply Last reply Reply Quote 0
                    • omz
                      omz last edited by

                      @Cethric I was able to get @JonB's example to work by replacing restype=glk4_union with restype=glk4 when reading back the position.

                      1 Reply Last reply Reply Quote 0
                      • Cethric
                        Cethric last edited by

                        @omz that seemed to fix it. Thanks

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        Powered by NodeBB Forums | Contributors