Am 26.02.10 16:32, schrieb darnzen:
On Feb 26, 3:15 am, "Diez B. Roggisch"<de...@nospam.web.de>  wrote:
Am 26.02.10 06:07, schrieb darnzen:





Having an odd problem that I solved, but wondering if its the best
solution (seems like a bit of a hack).

First off, I'm using an external DLL that requires static callbacks,
but because of this, I'm losing instance info. It could be import
related? It will make more sense after I diagram it:

#Module main.py
from A import *

class App:
      def sperg(self):
           self.a = A()

app = App()
[main loop and such]
   -----------------------------
# Module A.py
import main
class Foo:
        Selves=[]
       def __init__(self):
                 Foo.Selves.append(self)
       @staticmethod
       def chum_callback(nType, nP):
                 # Need to access function / data in app instance
                 app.sperg(nP)
                 # Need to access func data in Foo
                 # I'm pulling 'self' ouf of list made in constructor
                 self = Foo.getSelf(nP)

       def getSelf(nP):
                 return self.Selves[nP]

---------------------------------------------------------------------
So basically I added a list of instances to the base class so I can
get at them from the staticmethod.
What's bothering me the most is I can't use the global app instance in
the A.py module.

How can I get at the app instance (currently I'm storing that along
with the class instance in the constructor)?
Is there another way to do this that's not such a hack?

Sorry for the double / partial post :(

Can you show how you pass the staticmethod to the C-function? Is the DLL
utilized by ctypes?

I don't see any reason you couldn't use a bound method, which would give
you your self, instead relying on global state.

Diez

__main__.K<<  *facepalm* should of tried that!

Yeah I'm using ctypes. The DLL callback set ups are as follows. The
local callback is in the App namespace (in this case, some callbacks
are in different modules as noted in OP), but still no access to self:

         #Function wrapper
         A.expCallback = WINFUNCTYPE(None, c_int, c_int,  \
                                POINTER(Data_s))(A.Callback)

         #DLL call to register the local callback function
         DLLSetCallback(self.hID, A.SubID, EVENTID, A.expCallback)

     class A:
         #Local callback function
        @staticmethod
        def Callback(hID, SubID, Data):
              print 'I DON'T KNOW WHO I AM OR WHERE I CAME FROM!!'
              print 'BUT WITH hID, and SubID, I CAN FIGURE IT OUT'
              print 'IF I STORE A REFERENCE TO MYSELF IN A DICT'
              print 'USING KEY GENERATED FROM hID, SubID'
              pass

I'm not sure why they need to be static callbacks, but the DLL doc's
say "when using object based languages, such as c++, callback
functions must be declared as static functions and not instance
methods", and I couldn't get it to work without setting it up that
way. I could probably have them all be "classless" functions, but with
100's of these, my namespace would be polluted up the wazoo, and I'd
still have the problem that they wouldn't have access to instance
methods / properties.

The above code can't work with self, because you use

 A.expCallback

which at best can of course be a classmethod.

You need to instead invoke DLLSetCallback with a bound method, like this

 a = A()
 DLLSetCallback(self.hID, A.SubID, EVENTID, a.expCallback)

Also, the DLL-docs seem to refer to *C* or *C++*, where the concept of static functions is differently. If ctypes manages to get *some* callback passed, I'm 100% positive that it can pass *any* callable you like, including bound methods.

Diez
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to