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

苦于一直在网上找不到关于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)


未完待续




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值