用SWIG实现C++和Lua互相调用实例

来源:互联网 发布:网上银行系统繁忙淘宝 编辑:程序博客网 时间:2024/06/06 09:54

苦于一直在网上找不到关于C++和Lua互相调用的实例代码自己写了一份,比较乱以后有时间整理下。
主要涉及到
c++调用Lua函数。传递C++自定义类型
C++调用Lua函数,返回值是自定义类型
Lua函数根据传进来的自定义C++数据类型进行进行类成员操作。
打算有时间在做Lua返回New出来的C++自定义类型对象,实现内存回收方面的问题。
主要用到SWIG对C++自定义类型进行包装,方便Lua函数调用。

Lua.i文件,在vs里面右键属性页——》自定义生成步骤——》命令行输入swig -c++ -lua Lua_I.i 编译就可以自定生成后缀是CXX的文件

头文件class.h

#pragma onceclass  MyClass{public:    void    SetValueA(int iVlue);    void    SetValueB(float fValue);    int     GetValueInt(){ return m_iValueA; };    float   GetVlaueFloat(){ return m_fValueB; };protected:    private:    int     m_iValueA;    float   m_fValueB;};

源文件class.cpp

#include "stdafx.h"#include "class.h"void MyClass::SetValueA(int iVlue){    m_iValueA = iVlue;}void MyClass::SetValueB(float fVlue){    m_fValueB = fVlue;}
swig生成脚本lua_i.i
%module Lua_Interface%{    #include "Gobal.h"#include "class.h"#include "MainClass.h"#define  DEF_LuaPush(type)\void LuaPush(lua_State *L, type *Ptr)\{\SWIG_NewPointerObj(L, Ptr, SWIGTYPE_p_##type, 0);\}DEF_LuaPush(MyClass)DEF_LuaPush(ComputeClass)#define DEF_LuaToUserData(type)                             \void LuaToUserData(lua_State *L, int index, type **Ptr)\{\SWIG_Lua_ConvertPtr(L, index, (void**)Ptr, SWIGTYPE_p_##type, 0);\}DEF_LuaToUserData(MyClass)DEF_LuaToUserData(ComputeClass)%}class  MyClass{public:    void    SetValueA(int iVlue);    void    SetValueB(float fValue);    int     GetValueInt(){ return m_iValueA; };    float   GetVlaueFloat(){ return m_fValueB; };};class ComputeClass{public:    int ComputeAdd(MyClass& MyClassA, MyClass& MyClassB);    void ShowResult(int iValue);    MyClass*    GetMyClassPtr();};
测试类文件testclass.h
#pragma once#include "class.h"//class MyClass;class ComputeClass{public:    ComputeClass();    int         ComputeAdd(MyClass& MyClassA, MyClass& MyClassB);    void        ShowResult(int iValue);    MyClass*    GetMyClassPtr(){ return &m_MyClass; };    MyClass     m_MyClass;}; 

测试类文件testclass.cpp
#include "stdafx.h"#include "MainClass.h"#include "class.h"#include <iostream>using namespace std;ComputeClass::ComputeClass(){    m_MyClass.SetValueA(10101);    m_MyClass.SetValueB(20202.02);}int ComputeClass::ComputeAdd(MyClass& MyClassA, MyClass& MyClassB){    return MyClassA.GetValueInt() + MyClassB.GetValueInt();}void ComputeClass::ShowResult(int iValue){    cout<<"输出结果值:"<<iValue<<endl;}
main.cpp
// LuaTest.cpp : 定义控制台应用程序的入口点。//#include<stdio.h>#include<iostream>using namespace std;#include "I_LuaScript.h"#include "Gobal.h"#include "class.h"#include "MainClass.h"#ifdef __cplusplusextern "C" {#endif    int luaopen_Lua_Interface(lua_State* L);#ifdef __cplusplus}#endif#include "stdafx.h"#include "../lua/luaScript.h"#include "LuaPush.h"int _tmain(int argc, _TCHAR* argv[]){    char Incchar;    int IncInt = 2;    CLuaScript::CreateNew();    //swig初始化    luaopen_Lua_Interface(LuaScript()->GetHandle());    LuaScript()->LoadFile("ScriptTest.lua");    MyClass my1;    MyClass my2;    ComputeClass* pCompute = NULL;    MyClass* pMyClass = NULL;    my1.SetValueA(666);    my1.SetValueB(33.22);    my2.SetValueA(888);    my2.SetValueB(22.22);    ComputeClass cmp;    cmp.m_MyClass.SetValueA(7878);    cmp.m_MyClass.SetValueB(66.88);    //system("PAUSE");    while (cin>>IncInt && IncInt!= 0)    {        if (IncInt == 1)        {            if(LuaScript()->HasLuaFunc("ComputeValue"))            {                CallLuaFunc("ComputeValue",&my1, &my2, &cmp);            }        }        else if (IncInt == 2)        {            if(LuaScript()->HasLuaFunc("TestPrintd"))            {                CallLuaFunc("TestPrintd",&my1, &my2, &cmp);            }        }        else if (IncInt == 888)        {            LuaScript()->LoadFile("ScriptTest.lua");        }        else if (IncInt == 3)        {            if(LuaScript()->HasLuaFunc("ComputePrintd"))            {                CallLuaFunc("ComputePrintd",&my1, &my2, &cmp);            }        }        else if (IncInt == 4)        {            if(LuaScript()->HasLuaFunc("TestPrintdValue"))            {                CallLuaFunc("TestPrintdValue",IncInt);            }        }        else if (IncInt == 5)        {            if(LuaScript()->HasLuaFunc("TestGetPtr"))            {                CallLuaFunc("TestGetPtr",&cmp);            }        }        else if (IncInt == 6)        {            if(LuaScript()->HasLuaFunc("TestReturnPtr"))            {                CallScriptFunc_1I_Ret1I("TestReturnPtr",&cmp, &pCompute);                if (pCompute != NULL)                {                    cout<<"Lua函数返回指针对象输出GetValueInt():"<<pCompute->GetMyClassPtr()->GetValueInt()<<endl;                }            }        }        else if (IncInt == 7)        {            if(LuaScript()->HasLuaFunc("TestReturnProcessPtr"))            {                CallScriptFunc_1I_Ret1I("TestReturnProcessPtr",&my1, &pMyClass);                if (pMyClass != NULL)                {                    cout<<"Lua函数返回修改过的指针对象输出GetValueInt():"<<pMyClass->GetValueInt()<<endl;                }            }        }    }       CLuaScript::ReleaseLuaScript();return 0;}

根据生成的CXX文件函数生命Luapush.h
#pragma once#include "I_LuaScript.h"#define  PROTO_LuaPush(type)class type; void LuaPush(lua_State *L, type *Ptr);PROTO_LuaPush(MyClass)PROTO_LuaPush(ComputeClass)#define  PROTO_LuaToUserData(type)class type; void LuaToUserData(lua_State *L, int index, type **Ptr);PROTO_LuaToUserData(MyClass)PROTO_LuaToUserData(ComputeClass)


未完待续




原创粉丝点击