轉帖|其它|編輯:郝浩|2010-11-10 13:23:27.000|閱讀 1322 次
概述:最近使用C++寫服務器端的代碼,通過Socket監聽客戶端請求,解析客戶端請求中的參數,并根據解析后的結果,在服務端拼接SQL傳遞給數據庫執行。一想到C++中字符串解析以及字符串類型轉換,以及字符串的拼接...過來人都知道有多么痛苦,這不,我的Python工具-SqlBuilder也就應需求而生了,將Python嵌入到C++中,用Python代碼實現字符串的解析及加工,拼接等操作交給嵌入到C++中的Python引擎去執行,嗨,這下省力多了。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
最近使用C++寫服務器端的代碼,通過Socket監聽客戶端請求,解析客戶端請求中的參數,并根據解析后的結果,在服務端拼接SQL傳遞給數據庫執行。一想到C++中字符串解析以及字符串類型轉換,以及字符串的拼接...過來人都知道有多么痛苦,這不,我的Python工具-SqlBuilder也就應需求而生了,將Python嵌入到C++中,用Python代碼實現字符串的解析及加工,拼接等操作交給嵌入到C++中的Python引擎去執行,嗨,這下省力多了。
進入正題,這一次的實現主要有兩個目的:
一.如何將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構建工具
#-*-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(
if __name__ == "__main__":
print BuildSql("A_UpdateT_Table", """{"tablename":'t_table', 'tableid':12}""")
這個就是python的sqlbuilder工具,代碼說明:包含兩個部分:
1.SQL語句模板
2.構造SQL函數
參數說明:pTemplate 對應SQL模板中的SQL語句。
pValues: 通過客戶端請求參數(json格式),參考上述代碼中的測試代碼中給定的字符串格式
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:博客園