您的位置:首页 > 编程语言 > Lua

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

2012-05-29 16:46 701 查看
苦于一直在网上找不到关于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 once

class  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 __cplusplus
extern "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)


未完待续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: