What is causing SWIG to generate invalid code?

34 Views Asked by At

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;
}
0

There are 0 best solutions below