I am working on a Python front-end for some existing C++ libraries. As you can imagine, some of the C++ functions use the pass-by-reference method for some arguments. I do not know how to implement this kind of functions into python scripts, namely I should use a pointer to a struct as an argument, but I don't know how.
Note Even though python does not use pointers nor addresses explicitly, cppyy provides a way to access compiled libraries from python scripts. I guess that cppyy also covers this simple case and I am simply missing something like the correct syntax. I am using python 3.10 and cppyy 2.4.2.
Example pconf.h file:
struct Parser_Conf {
std::string filename = "";
uint32_t dump_addr_st = 0;
uint32_t dump_addr_end = 255;
bool debug_session = false;
bool use_xterm = true;
};
void print_conf(Parser_Conf ) ;
void print_conf_fromPtr(Parser_Conf * ) ;
Example pconf.cpp file:
#include <sstream>
struct Parser_Conf {
std::string filename = "";
uint32_t dump_addr_st = 0;
uint32_t dump_addr_end = 255;
bool debug_session = false;
bool use_xterm = true;
};
void print_conf(Parser_Conf ) ;
void print_conf_fromPtr(Parser_Conf * ) ;
Compiled library is in simplebuild/simple/libMINI.so. Example simple.py:
import os
import pysysc
#from cppyy import gbl as cpp
# more readable
import cppyy
#looks as it is not loaded by default
import cppyy.ll
cppyy.include('boost/any.hpp')
from cppyy.gbl import std, boost
build_dir= "simplebuild"
name = "PCONF Components"
myDir = os.path.dirname(os.path.realpath(__file__))
buildDir = os.path.join(myDir, build_dir)
program_file_name = "CSRAM_32Bits_macro.ihex"
if (not pysysc.load_systemc(17)):
print('Error : failed to load systemc dynamic library')
exit()
print("Loading " + name + " library")
#for HW-2-SW
pysysc.add_include_path(os.path.join(myDir, "simple"))
output = pysysc.add_library("pconf.h", "libMINI.so", buildDir)
parserConfCapsule = boost.any()
print("Preparing a Parser_Conf data")
parserConfCapsule.__assign__(cppyy.gbl.Parser_Conf())
print("Setting up the Parser_Conf data")
parserConfCapsule.type() == cppyy.typeid(cppyy.gbl.Parser_Conf)
print("=> Type of the 'parserConfCapsule' global:", type(parserConfCapsule).__name__)
extract = boost.any_cast[cppyy.gbl.Parser_Conf](parserConfCapsule)
print("=> Type of the 'extract' global:", type(extract).__name__)
print("Setting Parser_Conf fields")
extract.debug_session = False
extract.filename = program_file_name
print("Calling Library function with Parser_Conf struct")
cppyy.gbl.print_conf(extract)
print("Struct instance address is")
print(cppyy.ll.addressof(extract))
addr_of_extract = cppyy.ll.addressof(extract)
print("=> Type of the 'extract' global address:", type(addr_of_extract).__name__)
print("Q:Has the 'extract' global a deref? A:",
hasattr(extract, '__deref__') or hasattr(extract, 'dereference'))
print("Q:Has the 'extract' global address a deref? A:",
hasattr(addr_of_extract, '__deref__') or hasattr(addr_of_extract, 'dereference'))
print("Calling Library function with Parser_Conf address")
cppyy.gbl.print_conf_fromPtr(addr_of_extract)
Current output :
gre057823/PySysC-SC 236 >>python3 simple_example.py
SystemC 2.3.4-Accellera --- Jul 2 2025 14:37:58
Copyright (c) 1996-2022 by all Contributors,
ALL RIGHTS RESERVED
Loading PCONF Components library
Preparing a Parser_Conf data
Setting up the Parser_Conf data
=> Type of the 'parserConfCapsule' global: any
=> Type of the 'extract' global: Parser_Conf
Setting Parser_Conf fields
Calling Library function with Parser_Conf struct
Dump range : 0 - FF
Struct instance address is
93974867696144
=> Type of the 'extract' global address: int
Q:Has the 'extract' global a deref? A: False
Q:Has the 'extract' global address a deref? A: False
Calling Library function with Parser_Conf address
Traceback (most recent call last):
File "/home/360.1.417-StorAIge/USERS/lc177705/PySysC_TREE/PySysC-SC/simple_example.py", line 59, in <module>
cppyy.gbl.print_conf_fromPtr(addr_of_extract)
TypeError: void ::print_conf_fromPtr(Parser_Conf*) =>
TypeError: could not convert argument 1
I tried RTFM (https://cppyy.readthedocs.io/en/latest/lowlevel.html) but could not find a solution, any hints welcome.