我是C++语言的忠实拥趸,由于在上学时经历了资源匮乏的DOS时代,对C/C++这种更加接近硬件的语言由衷的喜爱。一直以来也是已C++作为工作的语言,对别的语言那是不屑一顾。在java火爆流行的时候,没有去深入了解过。现在看其实是一种损失,若非如此这篇博文或许能早几年就写出来了。然后由于工作的关系学了一点C#,在看到关于元数据的时候,萌生了在C++中实现类似功能的念头。后来接触过一些脚本语言,发现借助元数据是实现C++和脚本语言混合编程的好办法。

最初的时候,我尝试使用模板来实现这样的功能。经过一段时间的实践后,发现有些问题不易解决,而且用起来也不太方便,写了一半就放弃了。后来联想到微软使用idl这种接口描述语言来定义COM接口,决定使用类似的方法。大体就是定义一种接口描述语言,通过相应的编译器生成对应的C++头文件以及元数据描述代码,同时提供一个运行时库作为使用这些元数据的基础。这个编译器就是idlcpp,意为用接口描述语言生成C++代码,当然此处的idl不是微软的idl,只不过因意义相似,也用了同样的英文简写。

此idl语言到目前为止支持如下概念:命名空间,类和结构,数据成员,属性,方法,静态成员,虚函数,函数重载,运算符重载,多重继承,枚举,模板等。其中关键字大部分照抄的C++,所以乍看起来比较像C++代码。

除了idlcpp这个编译器外,还有一个基础的运行时库,以及针对不同的脚本语言相应的插件(目前只有lua和python),使用的开发工具是Visual Studio 2015,对非MS平台不太熟悉,所以暂时编译器只支持Windows平台(用到了一些Windows特有的函数)。不过运行时库没有用到特定平台的功能,较易移植到其他平台。此外还写了一些示例代码。上述所有代码托管在github上:https://github.com/fdyjfd/idlcpp/,另外还建了一个网站:http://idlcpp.org/ 目前网站还没什么内容,以后慢慢去丰富。

下面进入正题,先从工具的使用开始。

Idlcpp命令行工具

Idlcpp可以从github上下载代码编译得到,另外我也在网上放了一份已经编译好的执行文件,可以从 http://files.cnblogs.com/files/fdyjfd/idlcpp.zip 下载直接使用。若要自己编译idlcpp,请先从github上获取源代码。源代码结构如下:

其中idlcpp目录下是idlcpp的源代码。paf目录下是基础运行时库与脚本插件的代码。tutorials下是一些示例教程。目录bin是用来放置编译生成的dll及exe文件的,示例的lua和python脚本也放在这里。

编译idlcpp要用到第三方工具flex和bison。这两个工具可以从 https://sourceforge.net/projects/gnuwin32/ 下载。安装这两个工具后将其所在目录设置到环境变量Path中,以便编译时可以找到它们。编译成功后会在bin目录下生成idlcpp.exe。也可以下载我上传的以编译好的zip压缩包,将其解压到bin目录下,然后将bin目录也设置到环境变量Path中;或者将其解压到windows目录下供后面使用。

idlcpp通过编译接口描述文件(默认扩展名为.i),生成4个C++代码文件,分别是:

1. 相应的头文件(默认扩展名为.h)。

2. 内置函数的实现文件(默认扩展名为.ic)。

3. 元数据包装类的头文件(默认扩展名为.mh)。

4. 元数据包装类的实现文件(默认扩展名为.mc)。

运行cmd,进入idlcpp所在目录,运行命令idlcpp –h,结果如下图所示:

各选项含义为:

-h  显示帮助信息。

-ld  在生成的头文件中加入 #line 指令,用于编译器发现错误时正确定位到 .i文件中的对应位置。

-pc  指定运行时库pafcore头文件所在的路径。

-mp 元数据包装类的名字是根据对应类型的名字以及所在的命名空间生成的,此选项用于指定生成的元数据包装类型名的后缀,默认值为”_Type”。

-sp  用于生成子类代理类名字的后缀,默认值为”_Proxy”。子类代理类用于模拟脚本继承C++类型进而重写虚函数的功能。

-ic  指定内置函数的实现文件名的后缀,默认为”.ic”。

-mh  指定元数据头文件的后缀,默认为”.mh”。

-mc  指定元数据实现文件的后缀,默认为”.mc”。

-em  在Visual C++中,需用__declspec(dllexport)和__declspec(dllimport)处理dll中导出函数的情形,一般情况下用一个宏定义上述两者,在生成的元数据代码中也需要导出一些函数到dll中,此时idlcpp把此处定义的宏插到相应的代码处。

-I 将指定路径加入#import命令的搜索路径中。

编译paf

用Visual Studio 2015打开解决方案文件paf\build\vs2015\paf.sln

paf 中有3个工程,分别为:

1.  pafcore,这是基础的运行时库,提供了元数据的实现。相当于.Net中的System.Reflection或者java中的java.lang.reflect。

2.  paflua,这是lua的插件,用于pafcore和lua之间的交互,使用lua语言可以通过这个插件访问用户导出的各种功能。

3.  pafpython,这是python的插件,用于pafcore和python之间的交互,使用python语言可以通过这个插件访问用户导出的各种功能。

在pafcore工程中除了C++代码文件之外,还有许多idl的代码文件(扩展名为.i),如下图:

这些文件都是需要用idlcpp编译的。此处通过Custom Build Tool设置编译命令和选项,查看任意一个.i文件的属性,入下图所示:

在Visual Studio中可以通过属性文件简化Custom Build Tool的设置,pafcore所使用的属性文件在paf\build\vs2015\pafcore\pafcore.props。

设定好idlcpp.exe的路径以便系统可以找到它(比如设置环境变量Path或将其复制到Windows目录下)后即可编译pafcore工程。

工程paflua依赖lua,先从lua官网下载源文件编译后,再设置合适的头文件以及库文件路径,即可编译。

工程pafpython依赖python,先从python官网下载源文件编译后,再设置合适的头文件以及库文件路径,即可编译。

以上三个工程都会编译为Dll文件,默认放置在bin目录下。若是release版,文件名分别为pafcore.dll, paflua.dll和pafpython.dll。若是debug版,文件名分别为pafcore_d.dll, paflua_d.dll和pafpython_d.dll。

到现在为止,准备工作已经完成,下次开始介绍 tutorials 下的各个例子程序。

Lua语言的例子从这 C++混合编程之idlcpp教程Lua篇(2) 开始

Python语言的例子从这 C++混合编程之idlcpp教程Python篇(2) 开始

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Visual Studio 中可执行文件中嵌入的清单文件

    概要 本分步指南介绍如何在 Microsoft Visual Studio 2005年中的可执行文件 (.exe) 文件中嵌入的清单文件.如果您要开发"认证 Windows Vista&qu ...

  2. Maven实战(五)坐标详解

    1.为什么要定义Maven坐标      在我们开发Maven项目的时候,需要为其定义适当的坐标,这是Maven强制要求的.在这个基础上,其他Maven项目才能应用该项目生成的构件. 2.Maven坐 ...

  3. 误将文件push到Git,如何删除

    首先在本地删除多余文件夹(文件) 使用git add -u  git add -u,使用-u参数调用了git add命令,会将本地有改动(包括删除和修改)的已经追踪的文件标记到暂存区中.    再co ...

  4. CentOS 问题集锦

    在CentOS 6更新后,不可避免的会在启动选项中产生多个内核选项,一个内核文件大概占100兆左右(一般100M以下),可以使用以下命令进行删除多余的内核. 1.首先列出系统中正在使用的内核: # u ...

  5. 第八十八天请假 PHP smarty模板 变量调节器,方法和块函数基本书写格式

    变量调节器 : 文件命名格式(modifier.名称.php)  前端调用方式<{变量|名称:参数:参数……}>可组合使用,用|隔开 <?php /* 命名格式 smarty_mod ...

  6. VC++ AfxBeginThread 与 CreateThread 的区别

    简言之:AfxBeginThread是MFC的全局函数,是对CreateThread的封装.    CreateThread是Win32 API函数,前者最终要调到后者.具体说来,CreateThre ...

  7. Android之activity中新建控件

    了解了5大布局,我们会发现这些布局都是静态的,如何让系统自动生成控件呢?这就需要activity来帮忙了 今天我们讲的就是用activity新建布局 用案例来说吧! 实现一个输入行和列自动生成表格并生 ...

  8. oracle数据学习第一天

    SQL(Strutured Query Language):结构化查询语言 SQL可分为: <1>数据定义语言(DDL):Data Definition Language 用于建立.修改. ...

  9. AsyncTask异步加载和Gson

    public class MainActivity extends Activity {    private List<Goods> goods=new ArrayList<Goo ...

  10. Solaris 命令 小结

    Solaris 命令 小结 prstat -a 系统进程监控 Solaris 10默认的shell是sh,可以改成bash #useradd -m -d /home/dave dave -s /bin ...