creating_a_c_function.rst 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. .. _embedding_creating_a_c_function:
  2. ===================
  3. Create a C function
  4. ===================
  5. A native C function must have the following prototype: ::
  6. typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
  7. The parameters is an handle to the calling VM and the return value is an integer
  8. respecting the following rules:
  9. * 1 if the function returns a value
  10. * 0 if the function does not return a value
  11. * SQ_ERROR runtime error is thrown
  12. In order to obtain a new callable squirrel function from a C function pointer, is necessary
  13. to call sq_newclosure() passing the C function to it; the new Squirrel function will be
  14. pushed in the stack.
  15. When the function is called, the stackbase is the first parameter of the function and the
  16. top is the last. In order to return a value the function has to push it in the stack and
  17. return 1.
  18. Function parameters are in the stack from position 1 ('this') to *n*.
  19. *sq_gettop()* can be used to determinate the number of parameters.
  20. If the function has free variables, those will be in the stack after the explicit parameters
  21. an can be handled as normal parameters. Note also that the value returned by *sq_gettop()* will be
  22. affected by free variables. *sq_gettop()* will return the number of parameters plus
  23. number of free variables.
  24. Here an example, the following function print the value of each argument and return the
  25. number of arguments. ::
  26. SQInteger print_args(HSQUIRRELVM v)
  27. {
  28. SQInteger nargs = sq_gettop(v); //number of arguments
  29. for(SQInteger n=1;n<=nargs;n++)
  30. {
  31. printf("arg %d is ",n);
  32. switch(sq_gettype(v,n))
  33. {
  34. case OT_NULL:
  35. printf("null");
  36. break;
  37. case OT_INTEGER:
  38. printf("integer");
  39. break;
  40. case OT_FLOAT:
  41. printf("float");
  42. break;
  43. case OT_STRING:
  44. printf("string");
  45. break;
  46. case OT_TABLE:
  47. printf("table");
  48. break;
  49. case OT_ARRAY:
  50. printf("array");
  51. break;
  52. case OT_USERDATA:
  53. printf("userdata");
  54. break;
  55. case OT_CLOSURE:
  56. printf("closure(function)");
  57. break;
  58. case OT_NATIVECLOSURE:
  59. printf("native closure(C function)");
  60. break;
  61. case OT_GENERATOR:
  62. printf("generator");
  63. break;
  64. case OT_USERPOINTER:
  65. printf("userpointer");
  66. break;
  67. case OT_CLASS:
  68. printf("class");
  69. break;
  70. case OT_INSTANCE:
  71. printf("instance");
  72. break;
  73. case OT_WEAKREF:
  74. printf("weak reference");
  75. break;
  76. default:
  77. return sq_throwerror(v,"invalid param"); //throws an exception
  78. }
  79. }
  80. printf("\n");
  81. sq_pushinteger(v,nargs); //push the number of arguments as return value
  82. return 1; //1 because 1 value is returned
  83. }
  84. Here an example of how to register a function::
  85. SQInteger register_global_func(HSQUIRRELVM v,SQFUNCTION f,const char *fname)
  86. {
  87. sq_pushroottable(v);
  88. sq_pushstring(v,fname,-1);
  89. sq_newclosure(v,f,0); //create a new function
  90. sq_newslot(v,-3,SQFalse);
  91. sq_pop(v,1); //pops the root table
  92. return 0;
  93. }