在上一篇 C++混合编程之idlcpp教程(一) 中介绍了 idlcpp 工具的使用。现在对 idlcpp 所带的示例教程进行讲解,这里针对的 Lua 语言的例子。首先看第一个示例程序 LuaTutorial0。像很多语言的第一个例子一样,是一个打印 Hello world 的程序。用Visual Studio 2015打开解决方案文件 tutorials\LuaTutorials\LuaTutorials.sln,其下已经有多个工程文件。

在工程LuaTutorial0中,已经加入了三个文件,分别是 LuaTutorial0.cpp, Tutorial0.i, tutorial0.lua。首先看Tutorial0.i内容如下:

//tutorial

###include <stdio.h>

namespace tutorial
{
struct Test
{
static void Run();
};
#{
inline void Test::Run()
{
printf("Hello World!");
}
#}
}

看起来和C++代码较为相似。编译Tutorial0.i,将会生成Tutorial0.h,Tutorial0.mh,Tutorial0.ic,Tutorial0.mc四个文件。其中Tutorial0.h内容如下:

//DO NOT EDIT THIS FILE, it is generated by idlcpp
//http://www.idlcpp.org #pragma once #include <stdio.h> #line 4 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
namespace tutorial #line 5 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
{ #line 6 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
struct Test #line 7 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
{
public: #line 8 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
static void Run(); #line 9 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
}; inline void Test::Run()
{
printf("Hello World!");
} #line 16 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
}

因为在编译.i文件时指定了-ld选项,所以生成的.h文件中其中有许多#line指令,这是为下一步C++编译时能够定位错误到.i中的位置,而不是定位到.h上。修改编译选项,去掉-ld选项,重新编译,得到的结果如下:

//DO NOT EDIT THIS FILE, it is generated by idlcpp
//http://www.idlcpp.org #pragma once #include <stdio.h> namespace tutorial
{
struct Test
{
public: static void Run();
}; inline void Test::Run()
{
printf("Hello World!");
} }

这样看起来比较清爽了,请和上面的Tutorial0.i内容对照一下,基本上内容差不多。下面详细解释一下,首先是第一行

//tutorial

这是注释,idlcpp和C++一样用//表示单行注释,用/**/表示一块注释。

###include <stdio.h>

idlcpp只分析接口的声明,而C++头文件中一般还会出现其他的内容。此处idlcpp提供了将.i文件中的部分内容直接复制到.h的方法,一共有三种

  1. ##,表示将后续的一整行复制到.h的相应位置上,类似C++中的//注释一行。
  2. #{ 和 #},将在这两个符号之间的内容复制到.h的相应位置上,类似C++中的/*和*/注释一大块。
  3. #,表示将后续的一个标识符或整数复制到相应的位置。

这一行表示将#include <stdio.h>复制到.h中,下面的printf要用到这个头文件。

namespace tutorial 以及对应的{}。

namespace 和C++中的概念是一样的,会原样输出到.h中。

struct Test 以及对应的{}; 。

这个也和C++中概念类似,会原样输出到.h中。

下面.h文件中多了一行

public:

在idlcpp中声明的数据成员以及成员函数都被认为是public的,所以此处无脑加了这一行。

static void Run(); 这一行两边也是一样的,声明一个静态成员函数。

#{

inline void Test::Run()

{

printf("Hello World!");

}

#}

如上所述,idlcpp将#{和#}之间的内容复制到.h中。因为idlcpp只处理函数声明,不能处理其实现代码,所以无法向C++一样将其实现代码放在类的声明中,只能写在外面。此处为了少写一个.cpp文件,就用内联函数的方式写在头文件中。

文件Tutorial0.ic中没有实质性的内容。

文件Tutorial0.mh和Tutorial0.mc用于构建对应的元数据信息,具体内容牵涉太多,暂时不做解释。

再来看一下LuaTutorial0.cpp的内容

#include <tchar.h>
#include <string>
#include <windows.h> #include "lua.hpp"
#include "../../../paf/src/paflua/LuaWrapper.h"
#include "../../Common/Tutorial0.h"
#include "../../Common/Tutorial0.mh"
#include "../../Common/Tutorial0.ic"
#include "../../Common/Tutorial0.mc" #if defined(_DEBUG)
#pragma comment(lib,"pafcore_d.lib")
#pragma comment(lib,"paflua_d.lib")
#pragma comment(lib,"lua53_d.lib")
#else
#pragma comment(lib,"pafcore.lib")
#pragma comment(lib,"paflua.lib")
#pragma comment(lib,"lua53.lib")
#endif void GetExePath(std::string& path)
{
char fileName[MAX_PATH];
GetModuleFileName(, fileName, sizeof(fileName));
const char* end = _tcsrchr(fileName, '\\');
path.assign(fileName, end + );
} int _tmain(int argc, _TCHAR* argv[])
{
int error;
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaopen_paflua(L);
std::string path;
GetExePath(path);
path += "tutorial0.lua";
error = luaL_loadfile(L, path.c_str()) || lua_pcall(L, , , );
if (error)
{
fprintf(stderr, "%s\n", lua_tostring(L, -));
lua_pop(L, );
}
lua_close(L);
return ;
}

#include "lua.hpp"

这一行引入lua头文件

#include "../../../paf/src/paflua/LuaWrapper.h"

这一行引入lua插件头文件

#include "../../Common/Tutorial0.h"

#include "../../Common/Tutorial0.mh"

#include "../../Common/Tutorial0.ic"

#include "../../Common/Tutorial0.mc"

这几行将由Tutorial0.i编译的结果包含进来,这样编译后就会将对应的元数据信息注册到系统中,从而能够让脚步语言访问到。

main()函数中是一个运行一个lua脚步的基本过程。其中

luaopen_paflua(L);

这一行在lua虚拟机中加载插件。

最后看一下tutorial0.lua文件的内容

paf.tutorial.Test.Run();

这句代码表示调用C++中的::tutorial::Test::Run();

所有由idlcpp生成的数据类型都是在paf名字下,可以理解为lua中的名字paf等价于C++中的全局名字空间。在C++中,Run函数的全名可以认为是::tutorial::Test::Run,在lua中即为paf.tutorial.Test.Run。

编译链接后,执行结果如下图:

可以看到Lua正确调用了C++中的函数。

 

C++混合编程之idlcpp教程Lua篇(2)的更多相关文章

  1. C++混合编程之idlcpp教程Lua篇(9)

    上一篇在这 C++混合编程之idlcpp教程Lua篇(8) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相比,工程LuaTutorial7中除了四个文件LuaTutorial7.c ...

  2. C++混合编程之idlcpp教程Lua篇(8)

    上一篇在这 C++混合编程之idlcpp教程Lua篇(7) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程LuaTutorial6中,同样加入了四个文件:LuaTutori ...

  3. C++混合编程之idlcpp教程Lua篇(7)

    上一篇在这 C++混合编程之idlcpp教程Lua篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与LuaTutorial4工程相似,工程LuaTutorial5中,同样加入了四个文件: ...

  4. C++混合编程之idlcpp教程Lua篇(6)

    上一篇在这 C++混合编程之idlcpp教程Lua篇(5) 第一篇在这 C++混合编程之idlcpp教程(一) 工程LuaTutorial4中加入了四个文件:LuaTutorial4.cpp, Tut ...

  5. C++混合编程之idlcpp教程Lua篇(5)

    上一篇在这 C++混合编程之idlcpp教程Lua篇(4) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程LuaTutorial3中,同样加入了三个文件:LuaTutori ...

  6. C++混合编程之idlcpp教程Lua篇(4)

    上一篇在这  C++混合编程之idlcpp教程Lua篇(3) 与前面的工程相似,工程LuaTutorial2中,同样加入了三个文件 LuaTutorial2.cpp, Tutorial2.i, tut ...

  7. C++混合编程之idlcpp教程Lua篇(3)

    上一篇 C++混合编程之idlcpp教程Lua篇(2) 是一个 hello world 的例子,仅仅涉及了静态函数的调用.这一篇会有新的内容. 与LuaTutorial0相似,工程LuaTutoria ...

  8. C++混合编程之idlcpp教程Python篇(7)

    上一篇在这 C++混合编程之idlcpp教程Python篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与PythonTutorial4工程相似,工程PythonTutorial5中,同 ...

  9. C++混合编程之idlcpp教程Python篇(6)

    上一篇在这 C++混合编程之idlcpp教程Python篇(5) 第一篇在这 C++混合编程之idlcpp教程(一) 工程PythonTutorial4中加入了四个文件:PythonTutorial4 ...

随机推荐

  1. 解决EditorLineEnds.ttr被锁定导致Delphi2006-2010无法启动的问题

    在批处理最后增加了启动Delphi的命令.将批处理和Delphi放在同一目录即可. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  2. 0601 Spring2.0 发布会

    ProductBacklog:继续向下细化; 1.界面美化,统一界面风格,以简洁美观为主: 2.丰富版面的内容,吸引用户: 3.尝试增加新的版面: Sprint 计划会议:确定此次冲刺要完成的目标 1 ...

  3. java 中小数点的处理

    第一种 BigDecimal bg = new BigDecimal(f); double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleVa ...

  4. 27、初步探索echarts源码

    1.首先发现随笔中凡是和echarts相关的点击率都特别高,于是乎就接着写了echarts因为感觉要转点击率 首先声明我并不是专业做前端的,所以如果有些说得不对的地方,希望前端大神们出来指正 首先发现 ...

  5. ---iproute2 策略路由

    http://linux.chinaunix.net/techdoc/net/2007/03/30/953750.shtml 这篇文章写的例子讲明白策略路由的使用,但是本身好像不用这么麻烦, 用系统默 ...

  6. ios category,protocol理解

    category: 向现有的类中增加方法,同时提供方法的实现,现有类不需要做任何改动. protocol:(相当于Java或C#中的接口interface,当很多类都要需要类似的方法,但是方法具体实现 ...

  7. objective c,copy, mutableCopy区别

    copy总是返回不能被修改的对象,mutableCopy返回可以被修改的对象 例: NSArray *array = @[@"test", @"test2"]; ...

  8. python学习笔记3-celery分布式任务处理器

    celery是用python写的一个异步的任务框架,功能非常强大,具体的说明可以查看官网,这里主要提供点demo让你迅速使用该框架   1.环境安装 默认安装好了redis pip install c ...

  9. xcode archive 一直是灰色的

    把配置选择为device才能选build and archive的,模拟器的肯定不能build and anchive

  10. [原创]HEXO博客搭建日记

    博客系统折腾了好久,使用过Wordpress,Ghost,Typecho,其中Typecho是我使用起来最舒心的一种,Markdown编辑+轻量化设计,功能不多不少刚好,着实让我这种强迫症患者舒服了好 ...