Python

About

The Python module allows to execute Python source code. This can be standard Python as well as the classes included in the "c4d" and "maxon" module.

The module's API is defined in the python.framework as well as lib_py.h.

Classes and Functions

Example Code

// This example function executes the given Python code.
#include "maxon/vm.h"
#include "maxon/cpython.h"
#include "c4d_general.h"
#include "lib_py.h"
//----------------------------------------------------------------------------------------
// Executes the given Python code.
// @param[in] sourceCode The source code to execute.
// @param[in] doc The BaseDocument to set "doc" and "op". If no BaseDocument is set, "doc" and "op" will not be defined.
// @return OK on success.
//----------------------------------------------------------------------------------------
static maxon::Result<void> ExecutePythonScript(maxon::String& sourceCode, BaseDocument* doc)
{
// check code
if (sourceCode.IsEmpty())
return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
const maxon::VirtualMachineRef& vm = MAXON_CPYTHON27VM();
const maxon::VirtualMachineScopeRef scope = vm.CreateScope() iferr_return;
// init script
iferr (scope.Init("Python Script"_s, sourceCode, maxon::ERRORHANDLING::PRINT, nullptr))
{
const String errorMessage = "Error on Init()"_s;
return maxon::UnknownError(MAXON_SOURCE_LOCATION, errorMessage);
}
// only set "doc" and "op" if a BaseDocument is set.
// another option would be to set both "doc" and "op" to None
if (doc != nullptr)
{
// set "doc" and "op" variables
auto python = maxon::Cast<maxon::py::CPythonLibraryRef>(vm.GetLibraryRef());
maxon::py::CPythonGil gil(python);
// the new Python API from python.framework is compatible with the legacy Python API from lib_py.h.
// here we temporarily create an old PythonLibrary instance because it can create a PyObject
// from a BaseDocument and BaseObject
PythonLibrary pyLib;
auto* pyObjectDoc = pyLib.ReturnGeListNode(doc, false);
if (pyObjectDoc == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
auto* pyDoc = reinterpret_cast<maxon::py::NativePyObject*>(pyObjectDoc);
scope.Add("doc"_s, maxon::Data(pyDoc)) iferr_return;
python.CPy_Decref(pyDoc);
auto* pyObjectOp = op ? pyLib.ReturnGeListNode(op, false) : pyLib.ReturnPyNone();
if (pyObjectOp == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
auto* pyOp = reinterpret_cast<maxon::py::NativePyObject*>(pyObjectOp);
scope.Add("op"_s, maxon::Data(pyOp)) iferr_return;
python.CPy_Decref(pyOp);
}
// set __name__ = __main__
scope.Add("__name__"_s, maxon::Data("__main__"_s)) iferr_return;
// stop all current threads which are potentially modifying the current document,
// since the active script might modify the currently active document
// executes the script and returns when it got executed.
// info: if the script causes an unexpected infinite loop, Execute() does not return
// and there is no way to stop from the outside.
iferr (scope.Execute())
{
const String errorMessage = "Error on Execute()"_s;
return maxon::UnknownError(MAXON_SOURCE_LOCATION, errorMessage);
}
return maxon::OK;
}
c4d_general.h
maxon::py::NativePyObject
Definition: cpython_raw.h:268
BaseObject
Definition: c4d_baseobject.h:220
maxon::String
Definition: string.h:1197
maxon::Data
Definition: datatypebase.h:1086
maxon::OK
return OK
Definition: apibase.h:2490
vm.h
iferr_return
#define iferr_return
Definition: resultbase.h:1434
maxon::ERRORHANDLING::PRINT
@ PRINT
Any thrown exception will be handled internally.
MAXON_SOURCE_LOCATION
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:66
MAXON_CPYTHON27VM
#define MAXON_CPYTHON27VM()
Definition: vm.h:487
cpython.h
String
Definition: c4d_string.h:35
maxon::Result< void >
c4d_basedocument.h
StopAllThreads
void StopAllThreads(void)
iferr_scope
#define iferr_scope
Definition: resultbase.h:1343
maxon::String::IsEmpty
Bool IsEmpty() const
Definition: string.h:1387
cpython27_raw.h
iferr
#define iferr(...)
Definition: errorbase.h:380
BaseDocument::GetActiveObject
BaseObject * GetActiveObject(void)
BaseDocument
Definition: c4d_basedocument.h:479
errortypes.h
maxon::py::CPythonGil
Definition: cpython.h:2760