|
|
C++ to sqplus non 'int' member exporting
Last post 06-12-2008, 9:01 PM by terenctb. 6 replies.
-
07-31-2007, 7:19 AM |
-
suiram
-
-
-
Joined on 04-25-2006
-
Richmond Hill, ON
-
Posts 23
-
-
|
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 |
-
m0pey
-
-
-
Joined on 12-19-2005
-
Oxford
-
Posts 40
-
-
|
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 |
-
suiram
-
-
-
Joined on 04-25-2006
-
Richmond Hill, ON
-
Posts 23
-
-
|
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 |
-
suiram
-
-
-
Joined on 04-25-2006
-
Richmond Hill, ON
-
Posts 23
-
-
|
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 |
-
m0pey
-
-
-
Joined on 12-19-2005
-
Oxford
-
Posts 40
-
-
|
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 |
-
suiram
-
-
-
Joined on 04-25-2006
-
Richmond Hill, ON
-
Posts 23
-
-
|
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 |
-
terenctb
-
-
-
Joined on 06-13-2008
-
-
Posts 1
-
-
|
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).
|
|
|
|