这里是用 cpp 写了一个随机数模块,供 lua 使用。算是一个模板,供参考。
#include <lua.hpp>
#include <iostream>
using namespace std;
//#define LRANDOM_RAND_MAX 32767
class LRandomCPP {
public :
LRandomCPP() : _next(1) {
//cout << "default constructor function called." << endl;
}
LRandomCPP(unsigned long int seed) : _next(seed) {
//cout << "constructor function with a unsigned long int parameter called." << endl;
}
~LRandomCPP() {
//cout << "destructor function called." << endl;
}
unsigned long int getNext() {
return _next;
}
int rand() {
this->_next = this->_next * 1103515245 + 12345;
return ((unsigned)(this->_next / 65536) % LRANDOM_RAND_MAX);
}
double next() {
return (double)rand() * (1.0 / (double)(LRANDOM_RAND_MAX + 1.0));
}
int next(int up) {
return next(1, up);
}
int next(int low, int up) {
double r = next();
r *= (double)(up - low) + 1.0;
return (r + low);
}
static const int LRANDOM_RAND_MAX;
private :
unsigned long int _next;
//unsigned long int _foo;
};
const int LRandomCPP::LRANDOM_RAND_MAX = 32767;
static const char *libName = "lrandcpp";
static LRandomCPP **checkLRandomCPP(lua_State *L, int index) {
void *ud = luaL_checkudata(L, index, libName);
luaL_argcheck(L, NULL != ud, index, "LRandomCPP expected.");
return (LRandomCPP**)ud;
}
static int lnew(lua_State *L) {
unsigned long int seed = 1;
int n = lua_gettop(L);
if (0 != n) {
seed = (unsigned long int)luaL_checkinteger(L, 1);
}
void *ud = lua_newuserdata(L, sizeof(LRandomCPP*));
LRandomCPP **pp = (LRandomCPP**)ud;
*pp = new LRandomCPP(seed);
luaL_getmetatable(L, libName);
lua_setmetatable(L, -2); //attention: there is also a luaL_setmetatabel
return 1;
}
static int ldel(lua_State *L) {
LRandomCPP **pp = checkLRandomCPP(L, 1);
delete *pp;
return 0;
}
static int lnext(lua_State *L) {
lua_Integer low, up;
int n = lua_gettop(L);
LRandomCPP ** pp = checkLRandomCPP(L, 1);
double r = (*pp)->next();
switch (n) {
case 1:
lua_pushnumber(L, r);
return 1;
case 2:
low = 1;
luaL_checkinteger(L, 2);
break;
case 3:
low = luaL_checkinteger(L, 2);
up = luaL_checkinteger(L, 3);
break;
default:
return luaL_error(L, "wrong number of arguments.");
}
luaL_argcheck(L, low <= up, 2, "inteval is empty");
luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 2, "inteval too large");
r *= (double)(up - low) + 1.0;
lua_pushinteger(L, (lua_Integer)r + low);
return 1;
}
static int ltest(lua_State *L) {
LRandomCPP lrand0 = LRandomCPP(1);
LRandomCPP *p = new LRandomCPP(1);
cout << "seed:" << lrand0.getNext() << endl;
cout << "seed:" << p->getNext() << endl;
delete p;
p = NULL;
return 0;
}
extern "C"
int luaopen_lrandcpp(lua_State *L) {
const luaL_Reg l_m[] = {
{ "next", lnext },
{ NULL, NULL }
};
const luaL_Reg l_f[] = {
{ "new", lnew },
{ "next", lnext },
{ "test", ltest },
{ NULL, NULL }
};
luaL_newmetatable(L, libName);
lua_pushstring(L, "__gc");
lua_pushcfunction(L, ldel);
lua_rawset(L, -3);
lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_rawset(L, -3);
luaL_setfuncs(L, l_m, 0);
luaL_newlib(L, l_f);
return 1;
}