File: embed.cc

package info (click to toggle)
python-omniorb 3.6-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, stretch, wheezy
  • size: 3,128 kB
  • ctags: 3,321
  • sloc: cpp: 13,969; python: 8,883; sh: 2,576; xml: 107; makefile: 95; ansic: 35
file content (154 lines) | stat: -rw-r--r-- 3,816 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// embed.cc -- C++ part of embedding example

#include <iostream.h>
#include <echo.hh>
#include PYTHON_INCLUDE
#include <omniORBpy.h>


#ifdef __WIN32__
#define DLL_EXPORT _declspec(dllexport)
#else
#define DLL_EXPORT
#endif

class Echo_i : public POA_Echo,
	       public PortableServer::RefCountServantBase
{
public:
  inline Echo_i() {}
  virtual ~Echo_i() {}
  virtual char* echoString(const char* mesg);
};


char* Echo_i::echoString(const char* mesg)
{
  cout << "C++ upcall '" << mesg << "'" << endl;
  return CORBA::string_dup(mesg);
}

class InterpreterUnlocker {
public:
  InterpreterUnlocker() {
    tstate_ = PyEval_SaveThread();
  }
  ~InterpreterUnlocker() {
    PyEval_RestoreThread(tstate_);
  }
private:
  PyThreadState* tstate_;
};


// This function retrieves the omniORBpyAPI struct from the _omnipy
// Python module.
static omniORBpyAPI*
getAPI()
{
  PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy");
  if (!omnipy) {
    PyErr_SetString(PyExc_ImportError,
		    (char*)"Cannot import _omnipy");
    return 0;
  }
  PyObject* pyapi = PyObject_GetAttrString(omnipy, (char*)"API");
  omniORBpyAPI* api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
  Py_DECREF(pyapi);
  return api;
}


extern "C" {

  static PyObject* EmbedGetObjRef(PyObject* self, PyObject* args)
  {
    PyObject* pyorb;
    if (!PyArg_ParseTuple(args, (char*)"O", &pyorb)) return 0;

    omniORBpyAPI* api = getAPI();
    if (!api)
      return 0;

    CORBA::Object_var obj;
    CORBA::ORB_var    orb;

    try {
      // Python code gave us the ORB reference; convert it to the C++ reference
      obj = api->pyObjRefToCxxObjRef(pyorb, 1);
      orb = CORBA::ORB::_narrow(obj);
    }
    catch (CORBA::BAD_PARAM& ex) {
      PyErr_SetString(PyExc_TypeError,
		      (char*)"getObjRef() expects ORB as its argument");
      return 0;
    }
    // Activate an Echo object in the Root POA
    obj = orb->resolve_initial_references("RootPOA");
    PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);

    Echo_i* myecho = new Echo_i();
      
    PortableServer::ObjectId_var myechoid = poa->activate_object(myecho);

    obj = myecho->_this();
    myecho->_remove_ref();

    PortableServer::POAManager_var pman = poa->the_POAManager();
    pman->activate();

    // Return the Echo reference to Python
    PyObject* ret = api->cxxObjRefToPyObjRef(obj, 1);
    return ret;
  }

  static PyObject* EmbedPutObjRef(PyObject* self, PyObject* args)
  {
    PyObject* pyobj;
    if (!PyArg_ParseTuple(args, (char*)"O", &pyobj)) return 0;

    omniORBpyAPI* api = getAPI();
    if (!api)
      return 0;

    CORBA::Object_var obj;
    Echo_var eobj;
    try {
      obj = api->pyObjRefToCxxObjRef(pyobj, 1);
    }
    catch (CORBA::SystemException& ex) {
      PyErr_SetString(PyExc_TypeError,
		      (char*)"putObjRef() expects CORBA object argument");
      return 0;
    }
    eobj = Echo::_narrow(obj);
    if (CORBA::is_nil(eobj)) {
      PyErr_SetString(PyExc_TypeError,
		      (char*)"putObjRef() argument not an Echo");
      return 0;
    }
    {
      // To do the call into Python, we must release the Python
      // interpreter lock, since the code doing the upcall acquires
      // it. The InterpreterUnlocker class deals with it for us.
      InterpreterUnlocker _u;
      cout << "\nTrying call to Python object..." << endl;
      CORBA::String_var ret = eobj->echoString("Hello from C++");
      cout << "The result was '" << (char*)ret << "'" << endl;
    }

    Py_INCREF(Py_None);
    return Py_None;
  }

  static PyMethodDef embed_methods[] = {
    {(char*)"getObjRef", EmbedGetObjRef, METH_VARARGS},
    {(char*)"putObjRef", EmbedPutObjRef, METH_VARARGS},
    {NULL, NULL}
  };

  void DLL_EXPORT init_embed()
  {
    PyObject* m = Py_InitModule((char*)"_embed", embed_methods);
  }
}