关于泰#山¥众%筹Demo合约代码程序详细v-StPv888
c#执行lua代码
这里将分三个步骤:
加载lua代码到vm中,对应api-luaL_loadbuffer
luaL_loadbuffer会同时在栈上压入代码块的指针
执行lua代码,对应api-lua_pcall
lua_pcall会从栈上依次弹出{nargs}个数据作为函数参数,再弹出函数进行执行,并将结果压入栈
如果lua代码有返回值,那么通过lua_toXXX相关api从栈上获取结果
完整的代码如下:
private bool DoLuaCode(System.IntPtr L,string luaCode){
//加载lua代码
if(Lua.luaL_loadbuffer(L,luaCode,“”)==0){
//执行栈顶的函数
if(Lua.lua_pcall(L,0,1,0)==0){
//函数执行完成后,返回值会依次押入栈
return true;
}else{
Debug.LogError(“pcall failed!”);
return false;
}
}else{
Debug.LogError(“load buffer failed”);
return false;
}
}
假如我们有一段lua代码:
return’hello,i am from lua’
这段lua仅仅返回一段字符串,那么利用DoLuaCode去执行就是:
//lua代码
string luaCode=“return’hello,i am from lua’”;
if(DoLuaCode(L,luaCode)){
Debug.Log(Lua.lua_tostring(L,-1));
//lua_toXXX不会出栈,需要lua_pop才能出栈
Lua.lua_pop(L,1);
}
由于此处lua代码返回的是字符串,因此使用lua_tostring(L,-1)来将栈顶的元素转为字符串并返回,相应的我们还能看到有lua_tonumber,lua_toboolean等等.
4.c#调用lua全局函数
接下来的例子将说明一下c#端如何执行lua中的全局函数。
假设现在我们有一段lua代码如下:
function addSub(a,b)
return a+b,a-b;
end
通过DoLuaCode来运行以上的lua代码,就得到了一个全局的addSub函数,这个函数会返回a,b相加和相减的结果。
为了在c#端执行以上的lua函数,需要按以下步骤进行:
将全局函数压入栈中,对应api-lua_getglobal
将函数所需的参数依次压入栈中,对应api-lua_pushnumber
执行栈中函数,对应api-lua_pcall
获取函数返回结果,对应api-lua_tonumber
完整c#代码如下:
//从全局表里读取addSub函数,并压入栈
Lua.lua_getglobal(L,“addSub”);
//压入参数a
Lua.lua_pushnumber(L,101);
//压入参数b
Lua.lua_pushnumber(L,202);
//2个参数,2个返回值
Lua.lua_pcall(L,2,2,0);
//pcall会让参数和函数指针都出栈
//pcall执行完毕后,会将结果压入栈
Debug.Log(Lua.lua_tonumber(L,-2));
Debug.Log(Lua.lua_tonumber(L,-1));
Lua.lua_pop(L,2);
5.lua注册并调用c#静态函数
首先,想要被Lua调用的c#函数,都必须满足以下的格式:
public delegate int LuaCSFunction(System.IntPtr luaState);
同时需要加上特性:
MonoPInvokeCallback(typeof(LuaCSFunction))
我们可以通过以下方式,将一个LuaCSFunction注册到lua中:
static void RegisterCSFunctionGlobal(System.IntPtr L,string funcName,LuaCSFunction func){
//将LuaCSFunction压入栈中
Lua.lua_pushcfunction(L,func);
//lua_setglobal会弹出栈顶元素,并按给定的名字作为key将其加入到全局表
Lua.lua_setglobal(L,funcName);
}
那么,当我们在lua中执行c#注册的函数时,其交互过程如下:
LuaVM会临时分配一个局部栈结构(这里要区分开始通过luaL_newstate创建的全局栈,两者是独立的)
LuaVM会将lua侧的函数参数压入这个临时栈,然后将栈指针传给LuaCSFunction
LuaCSFunction在实现上需要从这个栈中读取lua侧压入的参数,然后执行真正的相关逻辑,并将最终结果压入栈中
LuaCSFunction需要返回一个int值,表示往栈中压入了多少个返回值
Lua从栈中获取C#侧压入的0/1/多个返回值
官方说明文档可以参考-Calling C from Lua
接下来将要演示如何将一个c#静态函数Print注入到lua中,实现lua中调用c#端的日志输出功能。
我们定义一个c#静态函数如下:
[MonoPInvokeCallback(typeof(LuaCSFunction))]
private static int Print(System.IntPtr localL){
//获取栈中元素个数
var count=Lua.lua_gettop(localL);
System.Text.StringBuilder s=new System.Text.StringBuilder();
for(var i=1;i<=count;i++){
//依次读取print的每个参数,合并成一个string
s.Append(Lua.lua_tostring(localL,i));
s.Append(‘’);
}
Debug.Log(s);
//print函数没有返回值
return 0;
}
lua_gettop可以获取栈中的元素个数,此处代表了lua端压入栈中的函数参数个数
然后我们通过以下方式将这个c#侧的Print注册到lua中,命名为print。
//将LuaCSFunction压入栈中
Lua.lua_pushcfunction(L,Print);
//lua_setglobal会弹出栈顶元素,并按给定的名字作为key将其加入到全局表
Lua.lua_setglobal(L,“print”);
接下来我们执行以下的lua代码:
print(‘hello’,‘csharp’)
就能看到编辑器中输出
hello csharp
6.lua注册c#类型
通常我们使用lua中的table来模拟c#中的类。一般类的注册思路如下:
在lua中创建一个与c#类同名的表
将c#类的静态函数都注册到lua的这个同名表里
下面演示一下如何将Unity中的Debug类注册到lua中:
Lua.lua_createtable(L,0,1);
Lua.lua_setglobal(L,“Debug”);
其实很简单:
lua_createtable会创建一个table,压入栈顶
lua_setglobal会弹出栈顶元素,并将其加到全局表里
这样我们在lua里就有了一个名为Debug的表可供全局访问。但目前这个表是空空如也的,我们还需要为其添加静态函数。(tips:实际上完整的设计中,还需要为class table设置metatable,增加一些限制性,但这里先不表)
6.1注入类的静态函数
首先我们定义一个符合LuaCSFunction形式的c#函数如下:
[MonoPInvokeCallback(typeof(LuaCSFunction))]
private static int Debug_Log(System.IntPtr L){
string msg=Lua.lua_tostring(L,1);
Debug.Log(msg);
return 0;
}
这个c#函数是对Debug.Log的一个封装。
然后可以通过以下方式将这个c#函数注册到lua中的Debug表中:
Lua.lua_createtable(L,0,1);
//往栈中压入字符串’Log’
Lua.lua_pushstring(L,“Log”);
//往栈中压入函数Debug_Log
Lua.lua_pushcfunction(L,Debug_Log);
//从栈中弹出一个元素作为key,再弹出一个元素作为value,作为pair赋值到index指定的table
Lua.lua_settable(L,1);
Lua.lua_setglobal(L,“Debug”);
众筹系统开发的步骤。
一、提交需求,确定合作意愿
首先,众筹系统开发商需要根据客户提出关于众筹系统网站建设的基本要求进行确认,如:系统前端结构设计,页面布局、后台功能和特殊定制等方面进行项目确定,后并表达确定双方间的合作。
第二、详谈众筹系统开发具体细节
确定一步的相关系统开发功能后,开发商便开始制定开发方案的具体细节,同时针对整个系统开发过程中需要的费用进行预估,等待客户确认金额。
第三、预估众筹系统开发周期和费用
此时,客户需要根据开发商的开发流程方案进行确认开发时间,即开发周期,同时对所提金额进行确认。
第四、确定众筹系统开发流程,签署正式合同
以上三个步骤完成后,双方便可以开始签署合作的协议,即合同类的文档资料,同时客户还需给予开发商一笔定金作为启动众筹系统开发制作的前奏,随后开发商也将按签订的协议进行系统开发。
第五、众筹系统模板设计并后确认
在众筹系统开发过程中,开发商应先设计出整个系统的模板及构架,同时针对客户在一流程中所提及到的功能应用一并设计后,与客户确认该模板及功能是否符合,如客户满意便可继续完善整个系统的细节部分,如还需修改,应及时跟进。
第六、众筹系统程序开发和测试
经过前面五大流程后,系统网站的各项制作均已完成后就需要交到程序员对后台系统功能实现的开发,同时在开发完成后便可以转为测试阶段。
第七、众筹系统开发后验收
待众筹系统开发商测试完毕后,就应让客户自己测试并验收,在此,小编想多说一句,作为客户本身的测试好找第三方专业技术开发商进行测试,毕竟如果自身的测试并没有具备专业人员的测试,只是简单的检查一遍,那如果后期有什么技术上的问题,那只能自身承担后果,因此交给另一个开发商测试或许是更好的决定。在测试结束并确认没有其他问题后,客户就该支付尾款。
第八、系统上线,跟进售后服务
作为开发商的一方,协助客户将众筹系统正式上线运营后,还需对系统后期的工作提供支持,这也是在签订合作协议中会提及到的重点,毕竟作为客户他们对整个系统的开发制作可能了解的不够具体,他们只能通过运营过程中存在的问题给予反馈,那开发商此时就该竭尽所能为客户的后期做好相关服务工作。