Python external_runtime example fixup

- Modify example to actually use the external runtime in example.cxx.
- Correct formatting of files.
- Add exception handling.
- Rename two main classes in example for better clarity.

This commit fixes the previous commit so that the example now correctly
tests the commmit prior to it.

Note that -builtin is not run as it does not work (seg faults - needs
investigation).

Issue #3067
This commit is contained in:
William S Fulton 2025-04-07 19:39:16 +01:00
parent 0954292130
commit 61f0bbe97d
4 changed files with 43 additions and 49 deletions

View File

@ -1,9 +1,29 @@
/* File : example.cxx */
#include <Python.h>
#include "swig_runtime.hxx"
#include <stdio.h>
#include "example.h"
Function::Function(PyObject * pyCallable)
: pyObj_(pyCallable), meshValue_(0)
{
// stuff happens in the typemap of PyObject * pyCallable
#include "swig_runtime.hxx"
MeshCaller::MeshCaller(PyObject *pyCallable) : pyObj_(pyCallable) {
if (pyObj_) {
PyObject *pyMesh = PyObject_CallMethod(pyObj_, const_cast<char *>("mesh"), const_cast<char *>("()"));
if (!pyMesh)
throw std::runtime_error("null pyMesh");
void *ptr = 0;
// Use SWIG_ConvertPtr and SWIG_TypeQuery in the SWIG external runtime
if (SWIG_IsOK(SWIG_ConvertPtr(pyMesh, &ptr, SWIG_TypeQuery("Mesh *"), 0))) {
Mesh *mesh = reinterpret_cast<Mesh *>(ptr);
if (!mesh)
throw std::runtime_error("null mesh");
const int value = mesh->value();
std::cout << "value = "<<value<<std::endl;
if (value != 42)
throw std::runtime_error("wrong value");
} else {
throw std::runtime_error("SWIG_ConvertPtr failed");
}
}
}

View File

@ -3,22 +3,15 @@
#include <iostream>
#include "Python.h"
class Mesh
{
class Mesh {
int value_;
public:
Mesh(const int value = 0)
: value_(value) {}
int value() { return value_;}
private:
int value_;
Mesh(const int value = 0) : value_(value) {}
int value() { return value_; }
};
class Function
{
class MeshCaller {
PyObject *pyObj_;
public:
explicit Function(PyObject * pyCallable = 0);
int meshValue() { return meshValue_;} int meshValue_;
private:
PyObject * pyObj_;
explicit MeshCaller(PyObject *pyCallable = 0);
};

View File

@ -1,30 +1,13 @@
/* File : example.i */
%module(docstring="external runtime") example
%{
#include "example.h"
%}
%typemap(in) PyObject * pyCallable
{
if ($input)
{
PyObject * pyMesh = PyObject_CallMethod($input, const_cast<char *>("mesh"), const_cast<char *>("()"));
if (!pyMesh)
throw std::runtime_error("null pyMesh");
void * ptr = 0;
if (SWIG_IsOK(SWIG_ConvertPtr(pyMesh, &ptr, SWIG_TypeQuery("Mesh *"), 0)))
{
Mesh *mesh = reinterpret_cast< Mesh * >(ptr);
if (!mesh)
throw std::runtime_error("null mesh");
const int value = mesh->value();
std::cout << "value="<<value<<std::endl;
if (value != 42)
throw std::runtime_error("wrong value");
}
}
}
// Exception handling
%include <std_except.i>
%catches(std::runtime_error) MeshCaller::MeshCaller;
%include "example.h"

View File

@ -5,18 +5,16 @@
import example
class PyFunction(object):
class MeshHolder(object):
def __init__(self):
self.__mesh = example.Mesh(42)
def mesh(self):
return self.__mesh
if not example.is_python_builtin():
obj = PyFunction()
f = example.Function(obj)
print('OK')
if example.is_python_builtin():
print("SWIG external runtime and builtin not currently working")
else:
obj = MeshHolder()
f = example.MeshCaller(obj)
# All done.
print("")
print("python exit")
print("All done")