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.


    Objc_util wants incorrect number of parameters

    Pythonista
    noise objc
    5
    17
    8238
    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

      check GKNoiseMap.alloc().initWithNoise_size_origin_sampleCount_seamless_.encoding

      or maybe

      GKNoiseMap.noiseMapWithNoise_size_origin_sampleCount_seamless_.encoding

      likely, pythonista got confused, and you will need to specify argtypes and restype in the call.

      Also, the origin and size arguments do not take tuples, they take some sort of vector2d, which is probably going to be a ctypes.double*2, and you will have to construct such an array.

      but one step at a time, post back on the encoding.

      1 Reply Last reply Reply Quote 1
      • ellie_ff1493
        ellie_ff1493 last edited by

        thanks, will try that and get back to you if it works

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

          It’s actually looking quite hard, how do I set a type I don’t have a reference to, I looked in the docs and it’s in a framework called simd

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

            it is probably an array of doubles. you need to print out the .encoding.

            1 Reply Last reply Reply Quote 0
            • cvp
              cvp @ellie_ff1493 last edited by cvp

              @ellie_ff1493 I tried, without success, this

              import objc_util
              from objc_util import *
              import ctypes
              
              objc_util.load_framework("GameplayKit")
              GKNoise = objc_util.ObjCClass("GKNoise")
              GKNoiseMap = objc_util.ObjCClass("GKNoiseMap")
              GKPerlinNoiseSource = objc_util.ObjCClass('GKPerlinNoiseSource')
              
              class vector_double2 (ctypes.Structure):
              	_fields_ = [('x', ctypes.c_float), ('y', ctypes.c_float)]
              
              class vector_int2 (ctypes.Structure):
              	_fields_ = [('x', ctypes.c_int), ('y', ctypes.c_int)]
              
              noiseSource = GKPerlinNoiseSource.alloc().init()
              noiseSource.frequency = 1
              noiseSource.octaveCount = 6
              noiseSource.lacunarity = 2
              noiseSource.persistence = 0.5
              
              noise = GKNoise.alloc().initWithNoiseSource(noiseSource)#make the noise algorithem 
              
              print('initWithNoise_size_origin_sampleCount_seamless_' in dir(GKNoiseMap.alloc()))#is what im calling valid
              
              
              newMap = GKNoiseMap.alloc().initWithNoise_(noise)
              # only to know parameters types
              print(dir(newMap))
              print(newMap.size())
              print(dir(newMap.origin()))
              print(newMap.sampleCount())
              print(newMap.isSeamless())
              
              
              size = vector_double2(10.0,10.0)
              origin = vector_double2(0.0,0.0)
              #origin = newMap.origin()
              #print(dir(origin))
              #print(type(origin))
              sampleCount = vector_int2(10,10)
              
              newMap = GKNoiseMap.alloc().initWithNoise_size_origin_sampleCount_seamless_(noise, size, origin, sampleCount, True, restype=GKNoiseMap, argtypes=[GKNoise, ctypes.POINTER(vector_double2), ctypes.POINTER(vector_double2),  ctypes.POINTER(vector_int2), c_bool])
              
              
              row  = []
              for x in range(10):
                  col = []
                  for y in range(10):
                      
                      col.append(newMap.interpolatedValueAtPosition_(position=(x/10,y/10)))
                  row.append(col)
                  
              print(row)
              print()
              
              

              I got error

              Traceback (most recent call last):
                File "/private/var/mobile/Containers/Shared/AppGroup/668A7D98-7216-47ED-917D-AA0B6173167E/Pythonista3/Documents/test4.py", line 43, in <module>
                  newMap = GKNoiseMap.alloc().initWithNoise_size_origin_sampleCount_seamless_(noise, size, origin, sampleCount, True, restype=GKNoiseMap, argtypes=[GKNoise, ctypes.POINTER(vector_double2), c_void_p,  ctypes.POINTER(vector_int2), c_bool])
                File "/var/containers/Bundle/Application/FED7F8B2-4F86-4833-BCFB-C2F8803CD0F1/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/objc_util.py", line 892, in __call__
                  objc_msgSend.argtypes = argtypes
              TypeError: item 3 in _argtypes_ has no from_param method
              
              
              1 Reply Last reply Reply Quote 0
              • JonB
                JonB last edited by

                can someone please print the .encoding attribute of the function you want to call?

                objc is self documenting, for the most part we don't have to guess what it wants.

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

                  @JonB

                  print(GKNoiseMap.alloc().initWithNoise_size_origin_sampleCount_seamless_.encoding)
                  

                  Gives

                  b'@68@0:8@16244056B64'
                  
                  1 Reply Last reply Reply Quote 0
                  • JonB
                    JonB last edited by

                    For your argtypes, first should be c_void_p, not GKNoise (that is what the error is saying. there are two hidden argtypes that get added, so your first is really the third... i think, i forget if you have to add the secret ones)

                    next, the signature calls for vectors, not pointers to the vectors. so remove POINTER. then your third arg is wrong... restype also should be c_void_p.

                    try this:

                    argtypes=[c_void_p, vector_double2, vector_double2, vector_int2, c_bool], restype=c_void_p
                    

                    you might need to add two c_void_p's at the start --i forget if objc_util does that for you (for the hidden _self and selector arguments to objc_msgSend)

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

                      @JonB Thanks as usual, how can I find an explanation of .encoding codes?
                      @ellie_ff1493 this works

                      import objc_util
                      from objc_util import *
                      import ctypes
                      
                      objc_util.load_framework("GameplayKit")
                      GKNoise = objc_util.ObjCClass("GKNoise")
                      GKNoiseMap = objc_util.ObjCClass("GKNoiseMap")
                      GKPerlinNoiseSource = objc_util.ObjCClass('GKPerlinNoiseSource')
                      
                      class vector_double2 (ctypes.Structure):
                      	_fields_ = [('x', ctypes.c_float), ('y', ctypes.c_float)]
                      
                      class vector_int2 (ctypes.Structure):
                      	_fields_ = [('x', ctypes.c_int), ('y', ctypes.c_int)]
                      
                      noiseSource = GKPerlinNoiseSource.alloc().init()
                      noiseSource.frequency = 1
                      noiseSource.octaveCount = 6
                      noiseSource.lacunarity = 2
                      noiseSource.persistence = 0.5
                      
                      noise = GKNoise.alloc().initWithNoiseSource(noiseSource)#make the noise algorithem 
                      
                      size = vector_double2(10.0,10.0)
                      origin = vector_double2(0.0,0.0)
                      sampleCount = vector_int2(10,10)
                      
                      newMap = GKNoiseMap.alloc().initWithNoise_size_origin_sampleCount_seamless_(noise, size, origin, sampleCount, True, argtypes=[c_void_p, vector_double2, vector_double2, vector_int2, c_bool], restype=c_void_p)
                      
                      
                      
                      row  = []
                      for x in range(10):
                          col = []
                          for y in range(10):
                              
                              col.append(newMap.interpolatedValueAtPosition_(position=(x/10,y/10)))
                          row.append(col)
                          
                      print(row)
                      print()
                      
                      
                      simon_hibbs 1 Reply Last reply Reply Quote 1
                      • JonB
                        JonB last edited by

                        see https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html

                        the encodings you get from introspection also have bytesize numbers after each character, which you can ignore.

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

                          @JonB Thanks

                          1 Reply Last reply Reply Quote 0
                          • simon_hibbs
                            simon_hibbs @cvp last edited by

                            @cvp I tried the code you posted above, but it doesn't work for me. I just get an array in which all the values are -1.0 and can't seem to get anything else out of the noise map.

                            I am finding using objc_util frustrating. Under what circumstances do I need to use the .alloc() method on an object? To be fair the Apple documentation on these classes is terrible. Putting all the documentation on a class and it's methods and properties on a single page in a consistent format can't be all that hard.

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

                              There is a difference between primitive ctypes structures and objc objects. If you are creating an objc object directly from a ObjCClass, with an init method, you need an alloc:

                              E.g.
                              

                              ObjCClass('SomeClass').alloc().initWithParameter_(value)

                              Some classes provide ways of directly giving you an object, or giving you a pointer to a shared object. So

                              ObjCClass('SomeClass').someClassWithParameter_(param)
                              

                              Or

                              ObjCClass('SomeClass').sharedSomeClass()

                              Also, .new() is short for .alloc().init().

                              So, if you are calling an init method you must use alloc. If not, not.

                              1 Reply Last reply Reply Quote 0
                              • cvp
                                cvp @simon_hibbs last edited by cvp

                                @simon_hibbs the intent of my code was only to help @ellie_ff1493, I did not try to understand the code it-self, sorry. Perhaps he could help you

                                To check if a class needs alloc() or not, I first do

                                Print(dir(ObjCClass('SomeClass')))
                                

                                and I see if alloc is in the list or not, then

                                Print(dir(ObjCClass('SomeClass').alloc()))
                                
                                simon_hibbs 1 Reply Last reply Reply Quote 0
                                • simon_hibbs
                                  simon_hibbs @cvp last edited by

                                  @cvp Ok, thanks. very helpful.

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

                                    Thank you all, this thread has been so very useful.

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