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

在工程PythonTutorial0中,已经加入了三个文件:PythonTutorial0.cpp, Tutorial0.i, tutorial0.py。首先看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 5 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
namespace tutorial #line 6 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
{ #line 7 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
struct Test #line 8 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
{
public: #line 9 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
static void Run(); #line 10 "D:/GitHub/idlcpp/tutorials/Common/Tutorial0.i"
}; inline void Test::Run()
{
printf("Hello World!");
} #line 17 "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的方法,一共有三种
- ##,表示将后续的一整行复制到.h的相应位置上,类似C++中的//注释一行。
- #{ 和 #},将在这两个符号之间的内容复制到.h的相应位置上,类似C++中的/*和*/注释一大块。
- #,表示将后续的一个标识符或整数复制到相应的位置。
这一行表示将#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用于构建对应的元数据信息,具体内容牵涉太多,暂时不做解释。
再来看一下PythonTutorial0.cpp的内容
#include <tchar.h>
#include <windows.h>
#include "Python.h"
#include "../../../paf/src/pafpython/PythonWrapper.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,"pafpython_d.lib")
#else
#pragma comment(lib,"pafcore.lib")
#pragma comment(lib,"pafpython.lib")
#endif int _tmain(int argc, _TCHAR* argv[])
{
const char* path = "tutorial0"; PyImport_AppendInittab("pafpython", &PyInit_PafPython); Py_Initialize();
PyObject* pName = PyUnicode_FromString(path);
PyObject* pModule = PyImport_Import(pName);
Py_DECREF(pName);
if(pModule != NULL)
{
Py_DECREF(pModule);
}
else
{
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", path);
}
Py_Finalize();
return ;
}
#include "Python.h"
这一行引入Python头文件
#include "../../../paf/src/pafpython/PythonWrapper.h"
这一行引入Python插件头文件
#include "../../Common/Tutorial0.h"
#include "../../Common/Tutorial0.mh"
#include "../../Common/Tutorial0.ic"
#include "../../Common/Tutorial0.mc"
这几行将由Tutorial0.i编译的结果包含进来,这样编译后就会将对应的元数据信息注册到系统中,从而能够让脚步语言访问到。
main()函数中是一个运行一个Python脚步的基本过程。其中
PyImport_AppendInittab("pafpython", &PyInit_PafPython);
这一行在Python中加载插件。
最后看一下tutorial0.py文件的内容
import pafpython;
paf = pafpython.paf; paf.tutorial.Test.Run();
最后这句代码表示调用C++中的::tutorial::Test::Run();
所有由idlcpp生成的数据类型都是在paf名字下,可以理解为Python中的名字pafpython.paf等价于C++中的全局名字空间。在C++中,Run函数的全名可以认为是::tutorial::Test::Run,在lua中即为pafpython.paf.tutorial.Test.Run。 编译链接后,执行结果如下图:

可以看到Python正确调用了C++中的函数。
C++混合编程之idlcpp教程Python篇(2)的更多相关文章
- C++混合编程之idlcpp教程Python篇(9)
上一篇在这 C++混合编程之idlcpp教程Python篇(8) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相比,工程PythonTutorial7中除了四个文件PythonTu ...
- C++混合编程之idlcpp教程Python篇(8)
上一篇在这 C++混合编程之idlcpp教程Python篇(7) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial6中,同样加入了四个文件:Pyt ...
- C++混合编程之idlcpp教程Python篇(7)
上一篇在这 C++混合编程之idlcpp教程Python篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与PythonTutorial4工程相似,工程PythonTutorial5中,同 ...
- C++混合编程之idlcpp教程Python篇(6)
上一篇在这 C++混合编程之idlcpp教程Python篇(5) 第一篇在这 C++混合编程之idlcpp教程(一) 工程PythonTutorial4中加入了四个文件:PythonTutorial4 ...
- C++混合编程之idlcpp教程Python篇(5)
上一篇在这 C++混合编程之idlcpp教程Python篇(4) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial3中,同样加入了三个文件:Py ...
- C++混合编程之idlcpp教程Python篇(4)
上一篇在这 C++混合编程之idlcpp教程Python篇(3) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial2中,同样加入了三个文件 Pyt ...
- C++混合编程之idlcpp教程Python篇(3)
上一篇 C++混合编程之idlcpp教程Python篇(2) 是一个 hello world 的例子,仅仅涉及了静态函数的调用.这一篇会有新的内容. 与PythonTutorial0相似,工程Pyth ...
- C++混合编程之idlcpp教程Lua篇(6)
上一篇在这 C++混合编程之idlcpp教程Lua篇(5) 第一篇在这 C++混合编程之idlcpp教程(一) 工程LuaTutorial4中加入了四个文件:LuaTutorial4.cpp, Tut ...
- C++混合编程之idlcpp教程Lua篇(9)
上一篇在这 C++混合编程之idlcpp教程Lua篇(8) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相比,工程LuaTutorial7中除了四个文件LuaTutorial7.c ...
随机推荐
- 移动手机专题rem布局实践+主要代码
HTML开头部分 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" / ...
- linux部分命令
打包ROOT文件夹tar -cvf ROOT3.tar ./ROOT 解压则相反 ps aux | grep tomcat 直接杀死tomcat sudo kill -9 进程号 rm -rf ./R ...
- Egret 压缩与解压(jszip)
一 jszip是什么 二 为什么要用jszip 三 如果使用zip 一 jszip是什么 jszip 是一个 JavaScript 库,可直接在浏览器上创建 zip 压缩档. 二 为什么要用jszip ...
- Eclipse下修改工程名
汇总下网上的方法. 一. 右键工程:Refactor->Rename,或选中工程按F2,修改名称 二. 右键工程:Properties->Web Project Settings,修改Co ...
- php json_encode中文unicode问题
php调用json_encode将中文字符串存入mysql后读取出来有问题,发现存进去的时候把'\'给去掉了.解决方法是调用json_encode时候后面加JSON_UNESCAPED_UNICODE ...
- linux进程及进程控制
Linux进程控制 程序是一组可执行的静态指令集,而进程(process)是一个执行中的程序实例.利用分时技术,在Linux操作系统上同时可以运行多个进程.分时技术的基本原理是把CPU的运行时间划 ...
- FTP\TFTP
FTP是文件传输协议的英文简写. FTP 文件传输协议 基于TCP,20和21端口. TFTP 简单文件传输协议,基于UDP,69 只能传输32Mb以下文件,不需要提供账号和密码.tftp xxx.x ...
- APK动态加载框架(DL)解析
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/39937639 (来自singwhatiwanna的csdn博客) 前言 好久 ...
- map/reduce of python
[map/reduce of python] 参考: http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac92 ...
- (转)linux获取/查看本机出口ip
获取/查看本机出口ip curl http://members.3322.org/dyndns/getip 1 curl ifconfig.me 2 #或者 3 curl http://member ...