浏览代码

封装变参接口。

sat23 4 年之前
父节点
当前提交
f4c99d4329
共有 3 个文件被更改,包括 204 次插入6 次删除
  1. 194 0
      CallPython/CallPython/CallPython.cpp
  2. 1 1
      CallPython/CallPython/CallPython.vcproj
  3. 9 5
      CallPython/CallPython/test.py

+ 194 - 0
CallPython/CallPython/CallPython.cpp

@@ -5,6 +5,9 @@
 #include "CallPython.h"
 // 添加Python头文件;
 #include "Python.h"
+#include <comdef.h> // _variant_t 结构体头文件;
+#include <Shlwapi.h>
+#include <vector>
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -17,10 +20,186 @@ CWinApp theApp;
 
 using namespace std;
 
+void PySetItem(PyObject* args, _variant_t var, int nIndex)
+{
+	if ( args == NULL || nIndex < 0 )
+		return;
+
+	switch(var.vt)  
+	{
+	case VT_BSTR:
+		{
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("s", var.bstrVal));
+			break;
+		}
+	case VT_LPSTR: //null terminated string
+		{
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("s", var.bstrVal));
+			break;
+		}
+	case VT_I1: //signed char
+		{
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("b", var.cVal));
+			break;
+		}
+	case VT_I2: //2 byte signed int   
+		{  
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("h", var.iVal));
+			break;  
+		} 
+	case VT_I4: //4 byte signed int 
+		{  
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("i", var.lVal));
+			break;  
+		}  
+	case VT_I8: //signed 64-bit int  
+		{  
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("k", var.lVal));
+			break;  
+		}
+	case VT_INT://signed machine int
+		{
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("i", var.intVal));
+			break;  
+		}
+	case VT_UI1: //unsigned char
+		{
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("B", var.cVal));
+			break;
+		}
+	case VT_UI2: //unsigned short   
+		{  
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("H", var.iVal));
+			break;  
+		} 
+	case VT_UI4: //unsigned long 
+		{  
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("I", var.lVal));
+			break;  
+		}  
+	case VT_UI8: //unsigned 64-bit int
+		{  
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("K", var.lVal));
+			break;  
+		}
+	case VT_UINT://unsigned machine int
+		{
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("I", var.intVal));
+			break;  
+		}
+	case VT_R4: //4 byte real  
+		{  
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("f", var.fltVal));
+			break;  
+		}  
+	case VT_R8: //8 byte real  
+		{  
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("f", var.dblVal));
+			break;  
+		}   
+	case VT_BOOL: //var is VARIANT_BOOL  
+		{  
+			PyTuple_SetItem(args, nIndex, Py_BuildValue("b", (var.boolVal == false) ? 0: 1));
+			break;  
+		}
+	case VT_CY: //var is CY type  
+	case VT_DATE: //var is DATE type  
+		{  
+			TRACE("UnSupport type %d\n",var.vt);
+			break;  
+		} 
+	default:  
+		{  
+			TRACE("Unknown type %d\n",var.vt);  
+			break;  
+		}  
+	}
+}
+
+// 注意:Py_Initialize、Py_Finalize由函数外部调用,以实现进程只初始化一次;
+//bool CallPython(std::string strPyPath, std::string strPyFuncName, int argc, _variant_t var, ...)
+PyObject *CallPython(std::string strPyPath, std::string strPyFuncName, int argc, ...)
+{
+	if ( !PathFileExists(strPyPath.c_str()) )
+		return NULL;
+
+	// 1、解析脚本路径和脚本名称;
+	std::string strPydir;
+	TCHAR szDrive[_MAX_DRIVE] = { 0 };
+	TCHAR szDir[_MAX_DIR] = { 0 };
+	TCHAR szExt[_MAX_EXT] = { 0 };
+	TCHAR szFilename[_MAX_FNAME] = { 0 };
+	TCHAR szScriptDir[MAX_PATH] = { 0 };
+	_tsplitpath_s(strPyPath.c_str(), szDrive, szDir, szFilename, szExt);
+	_stprintf_s(szScriptDir, _T("%s%s"), szDrive, szDir);
+	// 缓存一份路径;
+	strPydir = szScriptDir;
+	// 将'\'转换成'/', Python才设置运行目录成功;
+	int len = _tcslen(szScriptDir);
+	for (int i = 0; i < len; i++) {
+		if (szScriptDir[i] == '\\')
+			szScriptDir[i] = '/';
+	}
+
+	// 如果是当前文件,可能没带路径;
+	if ( szScriptDir[0] == '\0' )
+		_tcscpy_s(szScriptDir, _T("./"));
+
+	TCHAR szExecuteDir[MAX_PATH] = { 0 };
+	_stprintf_s(szExecuteDir, _T("sys.path.append('%s')"), szScriptDir);
+	// 添加系统模块,并指定当前脚本路径为运行路径;
+	PyRun_SimpleString("import sys");
+	PyRun_SimpleString(szExecuteDir);
+
+	// 2、导入模块;
+	PyObject *pModule = PyImport_ImportModule(szFilename);
+	if ( !pModule )
+		return NULL;
+
+	// 3、调用函数;
+	PyObject *pFunc = PyObject_GetAttrString(pModule, strPyFuncName.c_str());
+	if (!pFunc || !PyCallable_Check(pFunc))
+		return NULL;
+
+	// 4、导入函数参数;
+	PyObject *pRet = NULL;
+	if ( argc != 0 ) {		
+#if 0
+		PyObject *args = PyTuple_New(argc--);
+		PySetItem(args, var, 0);
+		// 收集所有变参;
+		va_list ap;
+		va_start(ap, argc); 
+		for ( int i = 0; i < argc; i++ ) {
+			_variant_t v = va_arg(ap, _variant_t);
+			PySetItem(args, v, i+1);
+		}
+		va_end(ap);
+#else
+		PyObject *args = PyTuple_New(argc);
+		// 收集所有变参;
+		va_list ap;
+		va_start(ap, argc); 
+		for ( int i = 0; i < argc; i++ ) {
+			_variant_t v = va_arg(ap, _variant_t);
+			PySetItem(args, v, i);
+		}
+		va_end(ap);
+#endif
+
+		pRet = PyObject_CallObject(pFunc, args);
+	}
+	else
+		pRet = PyEval_CallObject(pFunc, NULL);
+	
+	return pRet;
+}
+
 int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 {
 	int nRetCode = 0;
 
+	_variant_t a;
 	// 初始化 MFC 并在失败时显示错误
 	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
 	{
@@ -30,6 +209,7 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 	}
 	else
 	{
+#if 0
 		// 1、初始化Python环境  
 		Py_Initialize();
 
@@ -97,7 +277,21 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 
 		// 释放;
 		Py_Finalize();
+#else
+		Py_Initialize();
+		
+		//PyObject *pRet = CallPython("F:\\SAT\\SAT_API\\ssat_sdk\\device_manage\\testWizardClient.py", "API_UsbSwitch", 4,
+		PyObject *pRet = CallPython("test.py", "_print", 4,
+			// 变参一定要强转;
+			_variant_t(1),
+			_variant_t(2), 
+			_variant_t("aaa"),
+			_variant_t("bbb"));
+
+		pRet = CallPython("test.py", "Hello", 0);
 
+		Py_Finalize();
+#endif
 		system("pause");
 
 	}

+ 1 - 1
CallPython/CallPython/CallPython.vcproj

@@ -22,7 +22,7 @@
 			IntermediateDirectory="$(OutDir)\$(ConfigurationName)"
 			ConfigurationType="1"
 			UseOfMFC="2"
-			CharacterSet="1"
+			CharacterSet="2"
 			>
 			<Tool
 				Name="VCPreBuildEventTool"

+ 9 - 5
CallPython/CallPython/test.py

@@ -1,7 +1,11 @@
+# -*- coding:utf-8 -*-
 def Hello():
-	print("Hello world!")
-	
-	
+    print("Hello world!")
+
 def _add(x, y):
-	print('add',x, 'and', y)
-	return x + y
+    print('add',x, 'and', y)
+    return x + y
+
+def _print(x, y, s1, s2):
+    print u"输出变参", x, y, s1, s2
+    return x+y