Add external runtime Python example using typemap

See issue #3067
This commit is contained in:
Julien Schueller 2025-01-08 09:15:27 +01:00 committed by William S Fulton
parent 56afa6e6de
commit 0954292130
6 changed files with 120 additions and 0 deletions

View File

@ -9,6 +9,7 @@ enum
exception
exceptproxy
extend
external_runtime
funcptr
funcptr2
functor

View File

@ -0,0 +1,26 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS = -lm
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_run
build:
SWIG_LIB='$(SWIG_LIB_DIR)' $(SWIGEXE) -python $(SWIGOPT) -external-runtime swig_runtime.hxx
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static
clean:
rm -f swig_runtime.hxx
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' python_clean

View File

@ -0,0 +1,9 @@
#include <Python.h>
#include "swig_runtime.hxx"
#include "example.h"
Function::Function(PyObject * pyCallable)
: pyObj_(pyCallable), meshValue_(0)
{
// stuff happens in the typemap of PyObject * pyCallable
}

View File

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

View File

@ -0,0 +1,38 @@
/* 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");
}
}
}
%include "example.h"
%inline %{
// The -builtin SWIG option results in SWIGPYTHON_BUILTIN being defined
#ifdef SWIGPYTHON_BUILTIN
bool is_python_builtin() { return true; }
#else
bool is_python_builtin() { return false; }
#endif
%}

View File

@ -0,0 +1,22 @@
# file: runme.py
# This file illustrates the external runtime feature.
import example
class PyFunction(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')
# All done.
print("")
print("python exit")