I have been interfacing between Python and C using ctypes, and I have been trying to switch to using SWIG. However, the code generated by SWIG has errors and will not compile.
I have two .c files UTTT.c and UTTT_Library.c, a header file for both of the files, boardCount.h, and the interface file UTTT.i. I am using Windows Subsystem for Linux
After running swig -python UTTT.i
and gcc -c -fpic UTTT_wrap.c UTTT.c UTTT_Library.c -I/usr/local/include/python3.12
I get a compilation error in the code generated by SWIG:
UTTT_wrap.c: In function ‘_wrap_CGameState_board_set’:UTTT_wrap.c:3555:60: error: assignment to expression with array type for (; jj < (size_t)3; ++jj) arg1->board[ii][jj] = arg2[ii][jj];
I am unsure exactly what the issue with the array assignment is, but I am also confused why SWIG is not generating valid code.
Here is the contents of UTTT.i
%module UTTT%{ #include "boardCount.h"%}%include boardCount.h
This is what setup.py contains:
#!/usr/bin/env python3from distutils.core import setup, Extensionexample_module = Extension('_UTTT',sources = ['UTTT_wrap.cxx', 'UTTT_Library.c', "UTTT.c"])setup (name = 'UTTT', version = '0.1', author = "Robert Stegmann", description = """Library for ultimate tic tac toe""", ext_modules = [example_module], py_modules = ["UTTT"], )
Here is an excerpt from boardCount.h defining CGameState
#define ROW_DIMENSION 3#define COL_DIMENSION ROW_DIMENSIONtypedef struct { char board[9][ROW_DIMENSION][COL_DIMENSION]; char boardsWon[ROW_DIMENSION][COL_DIMENSION]; unsigned char currentBoard; unsigned char currentTurn; char gameWon;} CGameState;
Here is the code generated by SWIG that has the issue
SWIGINTERN PyObject *_wrap_CGameState_board_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; CGameState *arg1 = (CGameState *) 0 ; char (*arg2)[3][3] ; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; int res2 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; if (!PyArg_ParseTuple(args,(char *)"OO:CGameState_board_set",&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CGameState, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CGameState_board_set" "', argument " "1"" of type '" "CGameState *""'"); } arg1 = (CGameState *)(argp1); res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_a_3__a_3__char, 0 | 0 ); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CGameState_board_set" "', argument " "2"" of type '" "char [9][3][3]""'"); } arg2 = (char (*)[3][3])(argp2); { if (arg2) { size_t ii = 0; for (; ii < (size_t)9; ++ii) { if (arg2[ii]) { size_t jj = 0; for (; jj < (size_t)3; ++jj) arg1->board[ii][jj] = arg2[ii][jj]; } else { SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in variable '""board""' of type '""char [9][3][3]""'"); } } } else { SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in variable '""board""' of type '""char [9][3][3]""'"); } } resultobj = SWIG_Py_Void(); return resultobj;fail: return NULL;}