Squirrel

The programming language
Welcome to Squirrel Sign in | Join | Help
in Search

C++ to sqplus non 'int' member exporting

Last post 06-12-2008, 9:01 PM by terenctb. 6 replies.
Sort Posts: Previous Next
  •  07-31-2007, 7:19 AM 1983

    C++ to sqplus non 'int' member exporting


    Cannot export from a class/structure a fundamental member (long, short, insigned, float,..) different than int type
    //SQ-----------------------------------------------
    function FCall(p)
    {
        print(p.data);
         return 0;
    }

    //  CPP ------------------------------------------
              struct MyStruct
               {
        char   _data;              
    };
    or
    struct MyStruct
    {
        long   _data;              
    };
    //DECLARE_INSTANCE_TYPE(char);
    DECLARE_INSTANCE_TYPE(MyStruct);
    ..
    main()
    {
    ....
    SQClassDef<MyStruct>(_T("MyStruct")).
                            var(&MyStruct::_data,_T("data"));

     SquirrelFunction<int> FCall("FCall");
        MyStruct b;
        b._data = 3;
        (FCall)(&b);
    }
    I get at compilation time

    d:\mco_code_collection\_prjs\Getae\squirel\sqplus\sqplus.h(434) : error C2665: 'SqPlus::VarRef::VarRef' : none of the 3 overloads can convert parameter 2 from type ....

    If
    struct MyStruct
    {
        int   _data;              
    };
    works just fine.

    Thank you.




    Here is the whole cpp file:

    // testsq.cpp : Defines the entry point for the console application.
    //
    #define __ATLDB_H__ //prevent some ATL macros
    #include "stdafx.h"
    #include <conio.h>
    #include <stdarg.h>
    #include "sqplus.h"
    #include "sqplus2.h"
    using namespace SqPlus;


    struct MyStruct
    {
        char   _data;               // Does not work
        // int    _data;            // works fine with int
    };

    //DECLARE_INSTANCE_TYPE(char);
    DECLARE_INSTANCE_TYPE(MyStruct);


    //---------------------------------------------------------------------------------------
    //TCHAR* sq_includes[256] = { {_T("./")},0};
    void printfunc(HSQUIRRELVM v, const SQChar *lpszFormat, ...) ;


    //---------------------------------------------------------------------------------------
    int _tmain(int argc, _TCHAR* argv[])
    {
        SquirrelVM::Init();
        sq_setprintfunc(SquirrelVM::GetVMPtr(), printfunc); //sets the print function
        SquirrelObject main = SquirrelVM::CompileScript(_SC("testsq.nut"));
        SquirrelVM::RunScript(main);

        SQClassDef<MyStruct>(_T("MyStruct")).
                            var(&MyStruct::_data,_T("data"));

        SquirrelFunction<int> FCall("FCall");

        MyStruct b;
        b._data = 3;
     
        try{
            (FCall)(&b);
        }
        catch(SquirrelError &e)
        {
            printfunc(0, e.desc);
        }  

        SquirrelVM::Shutdown();
        getch();
        return 0;
    }


    //---------------------------------------------------------------------------------------
    void printfunc(HSQUIRRELVM v, const SQChar *lpszFormat, ...)
    {
        va_list args;
        va_start(args, lpszFormat);
        static char szBuffer[800];
        unsigned int nBuf = ::_vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(char), lpszFormat, args);
        va_end(args);
        printf(szBuffer);
    }


    #pragma comment(lib, "sqstdlibd.lib")
    #pragma comment(lib, "squirreld.lib")
    #pragma comment(lib, "sqplusd.lib")

  •  07-31-2007, 7:31 AM 1984 in reply to 1983

    Re: C++ to sqplus non 'int' member exporting

    I had this problem with unsigned int as well, if you goto line 168 in SqPlus.h you'll see

    // === Common Variable Types ===

    template<>
    struct TypeInfo<INT> {
      const SQChar * typeName;
      TypeInfo() : typeName(_T("int")) {}
      enum {TypeID=VAR_TYPE_INT,Size=sizeof(INT)};
      operator ScriptVarType() { return ScriptVarType(TypeID); }
    };

    All i did was add my own for unsigned int like this:


    template<>
    struct TypeInfo<unsigned int> {
      const SQChar * typeName;
      TypeInfo() : typeName(_T("unsigned int")) {}
      enum {TypeID=VAR_TYPE_UINT,Size=sizeof(unsigned int)};
      operator ScriptVarType() { return ScriptVarType(TypeID); }
    };

    and added VAR_TYPE_UINT to the enum on line 160 just after VAR_TYPE_INT.

    Not sure if this is the best way of getting round it but it worked for me.
  •  07-31-2007, 8:49 AM 1985 in reply to 1984

    Re: C++ to sqplus non 'int' member exporting

    Edited 15 minutes later
    It compiles, does not complain about types, it runs but the values are are on 32 bytes
    and seems to be completley wrong. So actually does not work

    Edited 10 minutes later
    ..................................I was wondering why ~int work and other types not
    so I removed all changes I've start doing  and I just trick the type to sq+
    beinbg INT for short,char snd long. Works fine and I  think will cover all situations.



    template<>
    struct TypeInfo<short> {
      const SQChar * typeName;
      TypeInfo() : typeName(_T("short")) {}
      enum {TypeID=VAR_TYPE_INT,Size=sizeof(short)};
      operator ScriptVarType() { return ScriptVarType(TypeID); }
    };


    Thank you.
    I already been there (here are chages I've added).
    Is strange work for unsigned int but not for any of long, short and char. It seems more complicated
    couse I thing the lexer does not support these types _RT_* types (squirrel.h) and also ot_ENUMS
    AND SQ*  types...

    template<typename T>
    void validateConstantType(T constant) {
      switch(TypeInfo<T>()) {
      case VAR_TYPE_INT:
      case VAR_TYPE_FLOAT:
        case VAR_TYPE_CHAR: //mco
        case VAR_TYPE_SHORT: //mco
        case VAR_TYPE_LONG: //mco
      case VAR_TYPE_BOOL:
      case VAR_TYPE_CONST_STRING:
        break;
      default:
        throw SquirrelError(_T("validateConstantType(): type must be INT, FLOAT, BOOL, or CONST CHAR *.\r\n"));
      } // case
    } // validateConstantType


    enum ScriptVarType {VAR_TYPE_NONE=-1,
                        VAR_TYPE_INT=0,
                        VAR_TYPE_FLOAT,
                        VAR_TYPE_LONG,
                        VAR_TYPE_CHAR,
                        VAR_TYPE_SHORT,
                        VAR_TYPE_BOOL,
                        VAR_TYPE_CONST_STRING,
                        VAR_TYPE_STRING,
                        VAR_TYPE_USER_POINTER,
                        VAR_TYPE_INSTANCE};


    template<>
    struct TypeInfo<char> {
      const SQChar * typeName;
      TypeInfo() : typeName(_T("char")) {}
      enum {TypeID=VAR_TYPE_CHAR,Size=sizeof(char)};
      operator ScriptVarType() { return ScriptVarType(TypeID); }
    };

    template<>
    struct TypeInfo<short> {
      const SQChar * typeName;
      TypeInfo() : typeName(_T("short")) {}
      enum {TypeID=VAR_TYPE_SHORT,Size=sizeof(short)};
      operator ScriptVarType() { return ScriptVarType(TypeID); }
    };

    template<>
    struct TypeInfo<long> {
      const SQChar * typeName;
      TypeInfo() : typeName(_T("long")) {}
      enum {TypeID=VAR_TYPE_LONG,Size=sizeof(long)};
      operator ScriptVarType() { return ScriptVarType(TypeID); }
    };


    10 minutes later ..................................
    work like this tricking the type at least in the small test program

    template<>
    struct TypeInfo<short> {
      const SQChar * typeName;
      TypeInfo() : typeName(_T("short")) {}
      enum {TypeID=VAR_TYPE_INT,Size=sizeof(short)};
      operator ScriptVarType() { return ScriptVarType(TypeID); }
    };
  •  07-31-2007, 9:27 AM 1987 in reply to 1985

    Re: C++ to sqplus non 'int' member exporting

    I stepped trough the code slowly enough to find out that the lexer does not support
    types smaler than 32bits. That's why a long, unsignned long, int, unsigned int on 32 bits sytems
    works fine. Any attempt to export a short or char fails on me. Changes are to complex. If I manage to get them working I;ll come back with the updates.
  •  08-01-2007, 6:07 AM 1993 in reply to 1987

    Re: C++ to sqplus non 'int' member exporting

    ** Only just seen your edit but this way also works **
    Did you change the case statements in SqPlus.cpp setVar and getVar as well?
    I know the StackHandler can only return int's which i think is what you're changing but you can add in your own type and cast them like this for a quick fix?

    getVar:
      case TypeInfo<unsigned>::TypeID: {
        if (!(vr->access & VAR_ACCESS_CONSTANT)) {
          unsigned * val = (unsigned *)data; // Address
          if (val) {
            return sa.Return(static_cast<int>(*val));
          } // if
        } else {
          unsigned * val = (unsigned *)&data; // Constant value
          return sa.Return(static_cast<int>(*val));
        }

    setVar:
      case TypeInfo<unsigned>::TypeID: {
          unsigned * val = (unsigned *)data; // Address
          if (val) {
              *val = sa.GetInt(3);
              return sa.Return(static_cast<int>(*val));
          } // if
          break;
      }
  •  08-01-2007, 9:20 AM 1995 in reply to 1993

    SOLVED Re: C++ to sqplus non 'int' member exporting SOLVED

    Adding new type for exporting/to from script
    Thank you. I did not find these in the first place. Now works fine. Let's sumarize all the changes
    for 'char' type to  have a record.

    Here is the test code
    // testsq.cpp : Defines the entry point for the console application.
    //
    #define __ATLDB_H__ //prevent some ATL macros that overlaps the sqplus namespace
    #define __RPCNDR_H__ //prevent some RPC macros that overlaps the sqplus namespace

    #include "stdafx.h"
    #include <conio.h>
    #include <stdarg.h>
    #include "sqplus.h"
    #include "sqplus2.h"
    //#include "sqplus3.h"
    using namespace SqPlus;


    struct MyStruct
    {
        char   _c;  
    };

    DECLARE_INSTANCE_TYPE(MyStruct);

    //---------------------------------------------------------------------------------------
    TCHAR* sq_includes[256] = { {_T("./")},0};

    void printfunc(HSQUIRRELVM v, const SQChar *lpszFormat, ...) ;


    //---------------------------------------------------------------------------------------
    int _tmain(int argc, _TCHAR* argv[])
    {
        SquirrelVM::Init();
        sq_setprintfunc(SquirrelVM::GetVMPtr(), printfunc); //sets the print function
        SquirrelObject main = SquirrelVM::CompileScript(_SC("testsq.nut"));
        SquirrelVM::RunScript(main);

        SQClassDef<MyStruct>(_T("MyStruct")).
                            var(&MyStruct::_c,_T("c"));

        SquirrelFunction<int> FCall("FCall");

        MyStruct b;
        b._c = 400;
        b.g  = 0;
     
        try{
            (FCall)(&b);
        }
        catch(SquirrelError &e)
        {
            printfunc(0, e.desc);
        }  

        SquirrelVM::Shutdown();
        getch();
        return 0;
    }


    //---------------------------------------------------------------------------------------
    void printfunc(HSQUIRRELVM v, const SQChar *lpszFormat, ...)
    {
        va_list args;
        va_start(args, lpszFormat);
        static char szBuffer[800];
        unsigned int nBuf = ::_vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(char), lpszFormat, args);
        va_end(args);
        printf(szBuffer);
    }


    #pragma comment(lib, "sqstdlibd.lib")
    #pragma comment(lib, "squirreld.lib")
    #pragma comment(lib, "sqplusd.lib")



    Here is the NUT file
    function FCall(p)
    {
        print(p.c+"\n");
        p.c = 5;
       
        print(p.c+"\n");
        return 0;
    }


    Here are the changes
    sqplus.cpp
      static int setVar(
      case TypeInfo<char>::TypeID: {
          char * val = (char*)data; // Address
          if (val) {
              *val = (char)sa.GetInt(3);
              return sa.Return(*val);
          } // if
          break;
     static int getVar()...
      case TypeInfo<char>::TypeID: {//mco
          if (!(vr->access & VAR_ACCESS_CONSTANT)) {
              char * val = (char *)data; // Address
              if (val) {
                  return sa.Return(*val);
              } // if
          } else {
              char * val = (char *)&data; // Constant value
              return sa.Return(*val);
          } // if
          break;

    sqplus.h
    enum ScriptVarType {VAR_TYPE_NONE=-1,
                        VAR_TYPE_INT=0,
                        VAR_TYPE_FLOAT,
                        VAR_TYPE_LONG,
                        VAR_TYPE_CHAR,// <---------
                        VAR_TYPE_BOOL,
                        VAR_TYPE_CONST_STRING,
                        VAR_TYPE_STRING,
                        VAR_TYPE_USER_POINTER,
                        VAR_TYPE_INSTANCE};

    template<>
    struct TypeInfo<char> {
      const SQChar * typeName;
      TypeInfo() : typeName(_T("char")) {}
      enum {TypeID=VAR_TYPE_CHAR,Size=sizeof(char)};
      operator ScriptVarType() { return ScriptVarType(TypeID); }
    };

    template<typename T>
    void validateConstantType(T constant) {
      switch(TypeInfo<T>()) {
      case VAR_TYPE_INT:
      case VAR_TYPE_FLOAT:
      case VAR_TYPE_CHAR: //<----
      case VAR_TYPE_LONG:
      case VAR_TYPE_BOOL:
      case VAR_TYPE_CONST_STRING:



  •  06-12-2008, 9:01 PM 2565 in reply to 1995

    Re: SOLVED Re: C++ to sqplus non 'int' member exporting SOLVED

    Although this does solve the compilation problems, it does not resolve that squirrel currently  doesn't handle unsigned integers (If you put  a large number using the template changes, you still get the signed bit). In order to resolve this, you will either have to add support to squirrel itself or just use other types (i.e. string, double).

    I looked at it I decided it was not worth doing as no data is loss anyway and it just a minor annoyance that comes with most languages (i.e. lua only handled doubles).


View as RSS news feed in XML
Powered by Community Server, by Telligent Systems