项目背景:
最近使用C++写服务器端的代码,通过Socket监听客户端请求,解析客户端请求中的参数,并根据解析后的结果,在服务端拼接SQL传递给数据库执行。
一想到C++中字符串解析以及字符串类型转换,以及字符串的拼接...过来人都知道有多么痛苦,头疼啊,腰也疼...
这不,我的Python工具-SqlBuilder也就应需求而生了,将Python嵌入到C++中,用Python代码实现字符串的解析及加工,拼接等操作交给嵌入到C++中的Python引擎去执行,嗨,这下省力多了,头不疼了,腰也不疼了,吃嘛嘛香...
ok,进入正题,这一次的实现主要有两个目的:
一.如何将Python嵌入到C++代码中
二.用Python实现一个简单的SqlBuilder工具
先简要说明一下我的本机环境:xp + vs2008 + python26
一.如何将Python嵌入到C++
1)安装python,如果您问具体怎么安装,请您老google一下,我使用的python26的版本,默认安装在c:\python26
2)设定vs2008 引入python头文件: tools->options->projects and solutions->vc++ directiories->add includes, add lib

3) 引入python头文件,这里注意,可能你会遇到编译时的错误,找不到python26_d.lib,或者遇到链接错误,如无法解析的外部符号 __imp___Py_RefTotal等错误,请按下列的步骤进行处理
对于错误1,请复制python26.lib,然后改名为python26_d.lib
对于错误2,请在引入python头文件前,加
#undef _DEBUG
#include <python.h>
4) 编写c++接口函数,函数内部实现python解析器的初始化,调用python代码,以及python解析器的卸载工作
具体代码如下:
1 #undef _DEBUG /* Link with python26.lib and not python26_d.lib */
2 #include <Python.h>
3
4 ///<Surmary>
5 /// 引入Python引擎构建Sql工具
6 /// 参数说明:
7 /// pTemplateName:对应Sql名称
8 /// pValues:客户端请求的Json字符串
9 ///</Surmary>
10 void SqlBuilder(const char* pTemplateName,const char* pValues, char* &sql)
11 {
12 PyObject *pArgs, *pName, *pModule, *pDict, *pFunc;
13 PyObject *pValue;
14
15 // 初始化python解析器引擎
16 Py_Initialize();
17
18 pName = PyString_FromString("SqlBuilder");
19 /* Error checking of pName left out */
20
21 pModule = PyImport_Import(pName);
22 Py_DECREF(pName);
23
24 if (pModule != NULL) {
25 pFunc = PyObject_GetAttrString(pModule, "BuildSql");
26 /* pFunc is a new reference */
27
28 if (pFunc && PyCallable_Check(pFunc)) {
29 pArgs = PyTuple_New(2);
30 pValue = PyString_FromString(pTemplateName);
31 if (!pValue) {
32 Py_DECREF(pArgs);
33 Py_DECREF(pModule);
34 fprintf(stderr, "Cannot convert argument pTempateName \n");
35 return;
36 }
37 /* pValue reference stolen here: */
38 PyTuple_SetItem(pArgs,0, pValue);
39
40 pValue = PyString_FromString(pValues);
41 if (!pValue) {
42 Py_DECREF(pArgs);
43 Py_DECREF(pModule);
44 fprintf(stderr, "Cannot convert argument pValue\n");
45 return;
46 }
47 PyTuple_SetItem(pArgs,1, pValue);
48 pValue = PyObject_CallObject(pFunc, pArgs);
49 Py_DECREF(pArgs);
50 if (pValue != NULL) {
51 sql = PyString_AsString(pValue);
52 printf("Result of call: %s\n", sql);
53 Py_DECREF(pValue);
54 }
55 else {
56 Py_DECREF(pFunc);
57 Py_DECREF(pModule);
58 PyErr_Print();
59 fprintf(stderr,"Call failed\n");
60 return;
61 }
62 }
63 else {
64 if (PyErr_Occurred())
65 PyErr_Print();
66 fprintf(stderr, "Cannot find function\"%s\"\n", "BuildSql");
67 }
68 Py_XDECREF(pFunc);
69 Py_DECREF(pModule);
70 }
71 else {
72 PyErr_Print();
73 fprintf(stderr, "Failed to load \"%s\" model\n", "SqlBuilder");
74 return;
75 }
76
77 // 卸载Python解析器引擎
78 Py_Finalize();
79
80 return;
81 }
ok,第一步工作完成后,已经实现了一个c++调用python代码的接口函数,现在再来实现第二部分,如何调用python代码,这里顺便实现一个sql构建工具

我的python工具-SqlBuilder#-*-coding:utf-8-*-
#SqlBuilder.py
from string import Template
dicSqlTemplate= {
"A_UpdateT_Table":"""update t_table set tablename = '${tablename}' where tableid= '${tableid}' """
}
def BuildSql(template,values):
return Template(dicSqlTemplate[template]).safe_substitute(eval(values))
if __name__ == "__main__":
print BuildSql("A_UpdateT_Table", """{"tablename":'t_table', 'tableid':12}""")
这个就是python的sqlbuilder工具,代码说明:
包含两个部分:
1.SQL语句模板
2.构造SQL函数
参数说明:pTemplate 对应SQL模板中的SQL语句
pValues: 通过客户端请求参数(json格式),参考上述代码中的测试代码中给定的字符串格式
ok,我的python工具-sqlbuilder,至此完工。如果上述代码在实验的过程中遇到问题,非常欢迎与我沟通交流,email:wdong0472@gmail.com, QQ:28358358(wdong)