Stefan Seefeld wrote:

I'm not sure what you are asking. Sticking to my example code, when you run the python script, 'instance' will be available in the global namespace, so you can make calls into it from Python. If that is not what you want, can you come up with another example ?

Thanks,
      Stefan

The problem is my lack of Python knowledge - the 35+ years assembler experience doesn't seem to count!!

I've attached a minimal set of files and a make file that I hope will illustrate the problem. I'm generating the bindings using pybindgen (version 0.10.0). I hope that just typing make will show all my mistakes!! The test1.py python script has the questions - how do I get the specific instance of the class already instantiated before calling the script to be referenced rather than a new instance. I'm passing the class pointer across to the script in a PyCObject but once in the python domain I don't have a clue as to what to do with it!!

Note - I'm specifically using pybindgen so I can read the generated code - Boost makes my brain hurt...

Cheers

--
Robin





=======================================================================
This email, including any attachments, is only for the intended
addressee.  It is subject to copyright, is confidential and may be
the subject of legal or other privilege, none of which is waived or
lost by reason of this transmission.
If the receiver is not the intended addressee, please accept our
apologies, notify us by return, delete all copies and perform no
other act on the email.
Unfortunately, we cannot warrant that the email has not been
altered or corrupted during transmission.
=======================================================================

# All of the sources participating in the build are defined here
C_SRCS = testclass.C testif.C

OBJS = testif.o testclass.o
C_DEPS = testif.C

# All Target
all: testclass

# Tool invocations
testclass: $(OBJS) testclassgen.py
        @echo 'Building target: $@'
        @echo 'Invoking: GCC C Linker'
        $(CXX)  -o "testclass" testclass.o testif.o -l python2.5
        @echo 'Finished building target: $@'
        @echo ' '

testif.C: testclass.H
        python testclassgen.py > testif.C
   
# Other Targets
clean:
        -$(RM) $(OBJS) $(C_DEPS) testclass *.pyc
        -...@echo ' '

.PHONY: all clean dependents
.SECONDARY:

INCLUDES+= -I. -I /usr/include/python2.5
CXX = g++
CC = gcc

WARNFLAGS +=  -W -Wall 

DEBUGFLAGS = -g

CXXFLAGS += -pipe -funit-at-a-time $(DEBUGFLAGS) $(INCLUDES) $(DEFINES) 
$(WARNFLAGS)

=======================================================================
This email, including any attachments, is only for the intended
addressee.  It is subject to copyright, is confidential and may be
the subject of legal or other privilege, none of which is waived or
lost by reason of this transmission.
If the receiver is not the intended addressee, please accept our
apologies, notify us by return, delete all copies and perform no
other act on the email.
Unfortunately, we cannot warrant that the email has not been
 altered or corrupted during transmission.
=======================================================================

'''test.py - Python source designed to demonstrate the use of python embedding'''

import testclass

class ReceiveData:

   def Receive(self, ptr, command, length, packet):
      print "Got command", command, "of length", length
      # how do I get the CObject in ptr into 'my' without creating a new instance
      my = testclass.testclass()
      # this as it is now will use another instance of testclass and return garbage
      print "Type should = 123, is = ", my.Gettype()
      print "Size should = 45, is = ", my.Getsize()
      return 0
      

      


// 1) setenv PYTHONPATH ${PYTHONPATH}:./
// 2) exe py_script class method command (int) length (int) data (string)
// eg. ./testclass test1 ReceiveData Receive 65 4 "aassddd"


#include <Python.h>
#include "testclass.H"


PyMODINIT_FUNC inittestclass(void);


static void delclass(void *ptr)
{
    testclass * oldclass = static_cast<testclass *>(ptr);
    delete oldclass;
    return;
}

int
main (int argc, char *argv[])
{
   PyObject *pName, *pModule, *pDict, *pClass, *pInstance, *pValue, *pCObject;

   if (argc < 5)
   {
      printf(" Not enough params\n");
      exit(1);
   }
   
   if (PyImport_AppendInittab("testclass", inittestclass) == -1)
   {
      printf("Couldn't append to initial table\n");
      return 1;
   }
   
   Py_Initialize ();
   pName = PyString_FromString (argv[1]);
   pModule = PyImport_Import (pName);
   if (PyErr_Occurred())
   {
	   PyErr_Print();
      return 1;
   }

   pDict = PyModule_GetDict (pModule);
   if (pDict == NULL)
   {
      printf ("Dictionary reference to %s not found\n", argv[1]);
      return 1;
   }

   // Build the name of a callable class 
   pClass = PyDict_GetItemString (pDict, "ReceiveData");
   if (pClass == NULL)
   {
      printf ("Class %s not found in module %s\n", "ReceiveData", argv[1]);
      return 1;
   }

   // Create an instance of the python class
   if (PyCallable_Check (pClass))
   {
      pInstance = PyObject_CallObject (pClass, NULL);
   }

// all ready to do our python stuff, lets set up some c++ stuff
   testclass *ptr = new testclass();
   ptr->Settype(123);
   ptr->Setsize(45);
   
   pCObject = PyCObject_FromVoidPtr(ptr, delclass);

   // Build parameter list
   pValue = PyObject_CallMethod (pInstance, "Receive", "(Oiis)", pCObject, atoi(argv[4]), atoi(argv[5]), argv[6]);

   if (pValue != NULL)
   {
      printf ("Return of call : %ld\n", PyInt_AsLong (pValue));
      Py_DECREF (pValue);
   }
   else
   {
      PyErr_Print ();
   }

   // Clean up
   Py_DECREF (pModule);
   Py_DECREF (pName);
   Py_Finalize ();

   return 0;
}




   class testclass
   {
    public:
      testclass () {}
      ~testclass () {}

      uint8_t Gettype () { return type;}
      uint16_t Getsize () { return size;}
      uint8_t Getprotover () { return protover;}
      uint16_t Getmsgno () { return msgno;}

      void Settype(uint8_t value) {type = value;}
      void Setsize(uint16_t value) {size = value;}
      void Setprotover(uint8_t value) {protover = value;}
      void Setmsgno(uint16_t value) {msgno = value;}

   private:
      uint8_t type;
      uint16_t size;
      uint8_t protover;
      uint16_t msgno;

   };
   
#! /usr/bin/env python

import sys

import pybindgen
from pybindgen import ReturnValue, Parameter, Module, Function, FileCodeSink
from pybindgen import CppMethod, CppConstructor, CppClass, Enum


def my_module_gen(out_file):

    mod = Module('testclass')
    mod.add_include('"testclass.H"')

    testclass = mod.add_class('testclass')
    testclass.add_constructor([])
    testclass.add_method('Gettype', ReturnValue.new('uint8_t'), [])
    testclass.add_method('Getsize',   ReturnValue.new('uint16_t'), [])
    testclass.add_method('Getprotover', ReturnValue.new('uint8_t'), [])
    testclass.add_method('Getmsgno', ReturnValue.new('uint16_t'), [])
    
    testclass.add_method('Settype', None, [Parameter.new('uint8_t', 'value')])
    testclass.add_method('Setsize', None,  [Parameter.new('uint16_t', 'value')])
    testclass.add_method('Setprotover', None, [Parameter.new('uint8_t', 'value')])
    testclass.add_method('Setmsgno', None, [Parameter.new('uint16_t', 'value')])


    mod.generate(FileCodeSink(out_file) )

if __name__ == '__main__':
    my_module_gen(sys.stdout)
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to