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 python3
from distutils.core import setup, Extension
example_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_DIMENSION
typedef 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;
}