|
@@ -5,6 +5,9 @@
|
|
#include "CallPython.h"
|
|
#include "CallPython.h"
|
|
// 添加Python头文件;
|
|
// 添加Python头文件;
|
|
#include "Python.h"
|
|
#include "Python.h"
|
|
|
|
+#include <comdef.h> // _variant_t 结构体头文件;
|
|
|
|
+#include <Shlwapi.h>
|
|
|
|
+#include <vector>
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#define new DEBUG_NEW
|
|
@@ -17,10 +20,186 @@ CWinApp theApp;
|
|
|
|
|
|
using namespace std;
|
|
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 _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
|
|
{
|
|
{
|
|
int nRetCode = 0;
|
|
int nRetCode = 0;
|
|
|
|
|
|
|
|
+ _variant_t a;
|
|
// 初始化 MFC 并在失败时显示错误
|
|
// 初始化 MFC 并在失败时显示错误
|
|
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
|
|
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
|
|
{
|
|
{
|
|
@@ -30,6 +209,7 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
|
|
+#if 0
|
|
// 1、初始化Python环境
|
|
// 1、初始化Python环境
|
|
Py_Initialize();
|
|
Py_Initialize();
|
|
|
|
|
|
@@ -97,7 +277,21 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
|
|
|
|
|
|
// 释放;
|
|
// 释放;
|
|
Py_Finalize();
|
|
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");
|
|
system("pause");
|
|
|
|
|
|
}
|
|
}
|