Change Python C Wrapper

This commit is contained in:
qianlifeng 2013-12-27 20:06:49 +08:00
parent bdf77b2782
commit 5893564f46
5 changed files with 123 additions and 64 deletions

View File

@ -1,69 +1,116 @@
#include <tchar.h>
#include "Python.h"
#include <thread>
#include <future>
extern "C" __declspec(dllexport) void InitPythonEnv()
{
Py_Initialize();
PyEval_InitThreads();
}
char* GetErrorMessage()
{
char *pStrErrorMessage = NULL;
if(PyErr_Occurred()){
PyObject *ptype, *pvalue, *ptraceback;
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
pStrErrorMessage = PyString_AsString(pvalue);
}
return pStrErrorMessage;
}
char* Exec(char* directory, char* file, char* method, char* para)
{
PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pClass, *pInstance;
char *error;
PyThreadState* global_state = PyThreadState_Get();
PyThreadState* ts = Py_NewInterpreter();
PyThreadState_Swap(ts);
// Initialise the Python interpreter
// Create GIL/enable threads
//PyGILState_STATE gstate = PyGILState_Ensure();
// // Get the default thread state
// PyThreadState* state = PyThreadState_Get();
// // Once in each thread
//PyThreadState* stateForNewThread = PyThreadState_New(state->interp);
//PyEval_RestoreThread(stateForNewThread);
// Build the name object
PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyString_FromString(directory));
pName = PyString_FromString(file);
error = GetErrorMessage();
if(error != NULL){
char* err =new char[5000]();
sprintf(error, "%s:%s","PYTHONERROR",error);
return err;
}
pModule = PyImport_Import(pName);
error = GetErrorMessage();
if(error != NULL){
char* err =new char[5000]();
sprintf(err, "%s:%s","PYTHONERROR",error);
return err;
}
pDict = PyModule_GetDict(pModule);
error = GetErrorMessage();
if(error != NULL){
char* err =new char[5000]();
sprintf(err, "%s:%s","PYTHONERROR",error);
return err;
}
pClass = PyDict_GetItemString(pDict,"PyWinAlfred");
error = GetErrorMessage();
if(error != NULL){
char* err =new char[5000]();
sprintf(err, "%s:%s","PYTHONERROR",error);
return err;
}
pInstance = PyObject_CallObject(pClass, NULL);
error = GetErrorMessage();
if(error != NULL){
char* err =new char[5000]();
sprintf(err, "%s:%s","PYTHONERROR",error);
return err;
}
// Call a method of the class with two parameters
pValue = PyObject_CallMethod(pInstance,method, "(s)",para);
error = GetErrorMessage();
if(error != NULL){
char* err =new char[5000]();
sprintf(err, "%s:%s","PYTHONERROR",error);
return err;
}
char * str_ret = PyString_AsString(pValue);
//PyEval_SaveThread();
// Finish the Python Interpreter
PyErr_Clear();
Py_EndInterpreter(ts);
PyThreadState_Swap(global_state);
return str_ret;
}
extern "C" __declspec(dllexport) char* ExecPython(char* directory, char* file, char* method, char* para)
{
try{
PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pClass, *pInstance;
// Initialise the Python interpreter
Py_Initialize();
// Create GIL/enable threads
//PyEval_InitThreads();
//PyGILState_STATE gstate = PyGILState_Ensure();
// // Get the default thread state
// PyThreadState* state = PyThreadState_Get();
// // Once in each thread
//PyThreadState* stateForNewThread = PyThreadState_New(state->interp);
//PyEval_RestoreThread(stateForNewThread);
// Build the name object
PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyString_FromString(directory));
pName = PyString_FromString(file);
// Load the module object
pModule = PyImport_Import(pName);
// pDict is a borrowed reference
pDict = PyModule_GetDict(pModule);
// pFunc is also a borrowed reference
pClass = PyDict_GetItemString(pDict,"PyWinAlfred");
if (PyCallable_Check(pClass))
{
pInstance = PyObject_CallObject(pClass, NULL);
}
else
{
PyErr_Print();
return "failed";
}
// Call a method of the class with two parameters
pValue = PyObject_CallMethod(pInstance,method, "(s)",para);
char * str_ret = PyString_AsString(pValue);
//PyGILState_Release(gstate);
//PyEval_SaveThread();
// Finish the Python Interpreter
//Py_Finalize();
return str_ret;
}
catch(int& value){
PyErr_Print();
}
auto future = std::async(Exec,directory,file,method,para);
return future.get();
}

View File

@ -103,7 +103,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PYWINALFRED_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PYWINALFRED_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>

View File

@ -68,8 +68,8 @@ namespace WinAlfred
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
{
string query = tbQuery.Text;
ThreadPool.QueueUserWorkItem(state =>
{
//ThreadPool.QueueUserWorkItem(state =>
//{
results.Clear();
foreach (PluginPair pair in plugins)
{
@ -98,7 +98,7 @@ namespace WinAlfred
resultCtrl.AddResults(results.OrderByDescending(o => o.Score).ToList());
resultCtrl.SelectFirst();
}));
});
//});
}
private void HideWinAlfred()

View File

@ -25,12 +25,24 @@ namespace WinAlfred.PluginLoader
try
{
string s = Marshal.PtrToStringAnsi(ExecPython(metadata.PluginDirecotry, metadata.ExecuteFileName.Replace(".py", ""), "query", query.RawQuery));
if (string.IsNullOrEmpty(s))
{
return new List<Result>();
}
if (s.StartsWith("PYTHONERROR"))
{
throw new ArgumentException(s);
}
List<PythonResult> o = JsonConvert.DeserializeObject<List<PythonResult>>(s);
List<Result> r = new List<Result>();
foreach (PythonResult pythonResult in o)
{
PythonResult ps = pythonResult;
ps.Action = () => ExecPython(metadata.PluginDirecotry, metadata.ExecuteFileName.Replace(".py", ""), ps.ActionName, ps.ActionPara);
if (!string.IsNullOrEmpty(ps.ActionName))
{
ps.Action = () => ExecPython(metadata.PluginDirecotry, metadata.ExecuteFileName.Replace(".py", ""), ps.ActionName, ps.ActionPara);
}
r.Add(ps);
}
return r;

View File

@ -152,7 +152,7 @@ namespace WinAlfred
var resultItemControl = pnlContainer.Children[index] as ResultItem;
if (resultItemControl != null)
{
resultItemControl.Result.Action();
if (resultItemControl.Result.Action != null) resultItemControl.Result.Action();
}
}