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.
    • Cethric
      Cethric last edited by

      I have done a bit more testing and noticed that this is only an issue for GLKVector(2|3|4) and not for any of the GLKMatrix structures.
      I have also updated the Github repo

      1 Reply Last reply Reply Quote 0
      • 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