diff --git a/pykd_ext/pyapi.h b/pykd_ext/pyapi.h index d2aa6dd..a852f5d 100644 --- a/pykd_ext/pyapi.h +++ b/pykd_ext/pyapi.h @@ -29,6 +29,7 @@ void __stdcall Py_DecRef(PyObject* object); PyObject* __stdcall PyString_FromString(const char *v); char* PyString_AsString(PyObject *string); +int PyString_Check(PyObject *o); PyObject* PyImport_Import(PyObject *name); PyObject* __stdcall PyImport_ImportModule(const char *name); @@ -72,12 +73,15 @@ int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v); PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name); PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args); PyObject* PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw); + PyObject* PyUnicode_FromWideChar(const wchar_t *w, size_t size); +int PyUnicode_Check(PyObject *o); PyObject* PyBool_FromLong(long v); PyObject* Py_None(); PyObject* PyExc_SystemExit(); +PyObject* PyExc_TypeError(); PyObject* PyType_Type(); PyObject* PyProperty_Type(); diff --git a/pykd_ext/pyclass.h b/pykd_ext/pyclass.h index be0f56e..68f209a 100644 --- a/pykd_ext/pyclass.h +++ b/pykd_ext/pyclass.h @@ -8,26 +8,41 @@ #include <string> #include <vector> + +class convert_python_exception : public std::exception +{ +public: + convert_python_exception(const char* message) : std::exception(message) + {} +}; + + struct convert_from_python { convert_from_python(PyObject* obj) : m_obj(obj){} operator std::wstring() { - if (IsPy3()) + if ( PyUnicode_Check(m_obj) ) { std::vector<wchar_t> buf(0x10000); size_t len = buf.size(); len = PyUnicode_AsWideChar(m_obj, &buf[0], len); return std::wstring(&buf[0], len); } - else + + if ( !IsPy3() && PyString_Check(m_obj) ) + { return std::wstring(_bstr_t(PyString_AsString(m_obj))); + } + + throw convert_python_exception("failed convert argument"); } + operator std::string() { - if (IsPy3()) + if (PyUnicode_Check(m_obj)) { std::vector<wchar_t> buf(0x10000); size_t len = buf.size(); @@ -35,8 +50,13 @@ struct convert_from_python std::wstring str(&buf[0], len); return std::string(_bstr_t(str.c_str())); } - else + + if ( !IsPy3() && PyString_Check(m_obj) ) + { return std::string(PyString_AsString(m_obj)); + } + + throw convert_python_exception("failed convert argument"); } PyObject* m_obj; @@ -116,11 +136,16 @@ static PyObject* getPythonClass() { \ struct Call_##fn { \ static PyObject* pycall(PyObject *s, PyObject *args) \ { \ - PyObject* self = PyTuple_GetItem(args, 0); \ - PyObject* cppobj = PyObject_GetAttrString(self, "cppobject"); \ - T* _this = reinterpret_cast<T*>(PyCapsule_GetPointer(cppobj, "cppobject")); \ - Py_DecRef(cppobj); \ - return _this->callMethod0(&fn); \ + try { \ + PyObject* self = PyTuple_GetItem(args, 0); \ + PyObject* cppobj = PyObject_GetAttrString(self, "cppobject"); \ + T* _this = reinterpret_cast<T*>(PyCapsule_GetPointer(cppobj, "cppobject")); \ + Py_DecRef(cppobj); \ + return _this->callMethod0(&fn); \ + } \ + catch(convert_python_exception& exc) \ + { PyErr_SetString(PyExc_TypeError(), exc.what()); } \ + return Py_None(); \ } \ }; \ {\ diff --git a/pykd_ext/pyinterpret.cpp b/pykd_ext/pyinterpret.cpp index c9c1315..b4a3e7e 100644 --- a/pykd_ext/pyinterpret.cpp +++ b/pykd_ext/pyinterpret.cpp @@ -61,6 +61,9 @@ public: PyObject* PyProperty_Type; PyObject* Py_None; PyObject* PyExc_SystemExit; + PyObject* PyExc_TypeError; + PyObject* PyUnicode_Type; + PyObject* PyString_Type; PyThreadState* PyThreadState_Current; @@ -111,7 +114,8 @@ public: PyObject* ( *PyMethod_New)(PyObject *func, PyObject *self, PyObject *classobj); PyObject* ( *PyCapsule_New)(void *pointer, const char *name, PyCapsule_Destructor destructor); void* ( *PyCapsule_GetPointer)(PyObject *capsule, const char *name); - int( *PyObject_SetAttrString)(PyObject *o, const char *attr_name, PyObject *v); + int ( *PyObject_SetAttrString)(PyObject *o, const char *attr_name, PyObject *v); + int ( *PyObject_IsInstance)(PyObject *inst, PyObject *cls); PyObject* ( *PyUnicode_FromWideChar)(const wchar_t *w, size_t size); PyObject* ( *PyBool_FromLong)(long v); size_t( *PyList_Size)(PyObject* list); @@ -405,10 +409,12 @@ PyModule::PyModule(int majorVesion, int minorVersion) *reinterpret_cast<FARPROC*>(&PyType_Type) = GetProcAddress(m_handlePython, "PyType_Type"); *reinterpret_cast<FARPROC*>(&PyProperty_Type) = GetProcAddress(m_handlePython, "PyProperty_Type"); + *reinterpret_cast<FARPROC*>(&PyUnicode_Type) = GetProcAddress(m_handlePython, "PyUnicode_Type"); + *reinterpret_cast<FARPROC*>(&PyString_Type) = GetProcAddress(m_handlePython, "PyString_Type"); *reinterpret_cast<FARPROC*>(&Py_None) = GetProcAddress(m_handlePython, "_Py_NoneStruct"); PyExc_SystemExit = *reinterpret_cast<PyObject**>(GetProcAddress(m_handlePython, "PyExc_SystemExit")); + PyExc_TypeError= *reinterpret_cast<PyObject**>(GetProcAddress(m_handlePython, "PyExc_TypeError")); PyThreadState_Current = reinterpret_cast<PyThreadState*>(GetProcAddress(m_handlePython, "_PyThreadState_Current")); - *reinterpret_cast<FARPROC*>(&Py_Initialize) = GetProcAddress(m_handlePython, "Py_Initialize"); *reinterpret_cast<FARPROC*>(&Py_Finalize) = GetProcAddress(m_handlePython, "Py_Finalize"); *reinterpret_cast<FARPROC*>(&Py_NewInterpreter) = GetProcAddress(m_handlePython, "Py_NewInterpreter"); @@ -432,6 +438,7 @@ PyModule::PyModule(int majorVesion, int minorVersion) *reinterpret_cast<FARPROC*>(&PyObject_GetAttrString) = GetProcAddress(m_handlePython, "PyObject_GetAttrString"); *reinterpret_cast<FARPROC*>(&PyObject_SetAttr) = GetProcAddress(m_handlePython, "PyObject_SetAttr"); *reinterpret_cast<FARPROC*>(&PyObject_CallObject) = GetProcAddress(m_handlePython, "PyObject_CallObject"); + *reinterpret_cast<FARPROC*>(&PyObject_IsInstance) = GetProcAddress(m_handlePython, "PyObject_IsInstance"); *reinterpret_cast<FARPROC*>(&PyTuple_New) = GetProcAddress(m_handlePython, "PyTuple_New"); *reinterpret_cast<FARPROC*>(&PyTuple_SetItem) = GetProcAddress(m_handlePython, "PyTuple_SetItem"); *reinterpret_cast<FARPROC*>(&PyTuple_GetItem) = GetProcAddress(m_handlePython, "PyTuple_GetItem"); @@ -459,6 +466,8 @@ PyModule::PyModule(int majorVesion, int minorVersion) *reinterpret_cast<FARPROC*>(&PyObject_SetAttrString) = GetProcAddress(m_handlePython, "PyObject_SetAttrString"); *reinterpret_cast<FARPROC*>(&PyUnicode_FromWideChar) = isPy3 ? GetProcAddress(m_handlePython, "PyUnicode_FromWideChar") : GetProcAddress(m_handlePython, "PyUnicodeUCS2_FromWideChar"); + *reinterpret_cast<FARPROC*>(&PyUnicode_AsWideChar) = isPy3 ? GetProcAddress(m_handlePython, "PyUnicode_AsWideChar") : + GetProcAddress(m_handlePython, "PyUnicodeUCS2_AsWideChar"); *reinterpret_cast<FARPROC*>(&PyImport_Import) = GetProcAddress(m_handlePython, "PyImport_Import"); *reinterpret_cast<FARPROC*>(&PyImport_AddModule) = GetProcAddress(m_handlePython, "PyImport_AddModule"); *reinterpret_cast<FARPROC*>(&PyBool_FromLong) = GetProcAddress(m_handlePython, "PyBool_FromLong"); @@ -468,7 +477,7 @@ PyModule::PyModule(int majorVesion, int minorVersion) *reinterpret_cast<FARPROC*>(&PyFile_AsFile) = GetProcAddress(m_handlePython, "PyFile_AsFile"); *reinterpret_cast<FARPROC*>(&PyUnicode_FromString) = GetProcAddress(m_handlePython, "PyUnicode_FromString"); *reinterpret_cast<FARPROC*>(&PyInstanceMethod_New) = GetProcAddress(m_handlePython, "PyInstanceMethod_New"); - *reinterpret_cast<FARPROC*>(&PyUnicode_AsWideChar) = GetProcAddress(m_handlePython, "PyUnicode_AsWideChar"); + *reinterpret_cast<FARPROC*>(&_Py_fopen) = GetProcAddress(m_handlePython, "_Py_fopen"); *reinterpret_cast<FARPROC*>(&Py_AddPendingCall) = GetProcAddress(m_handlePython, "Py_AddPendingCall"); *reinterpret_cast<FARPROC*>(&PyGILState_Ensure) = GetProcAddress(m_handlePython, "PyGILState_Ensure"); @@ -708,6 +717,11 @@ PyObject* PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw) return PythonSingleton::get()->currentInterpreter()->m_module->PyObject_Call(callable_object, args, kw); } +int PyObject_IsInstance(PyObject *inst, PyObject *cls) +{ + return PythonSingleton::get()->currentInterpreter()->m_module->PyObject_IsInstance(inst,cls); +} + PyObject* __stdcall PyTuple_New(size_t len) { return PythonSingleton::get()->currentInterpreter()->m_module->PyTuple_New(len); @@ -758,6 +772,11 @@ PyObject* PyExc_SystemExit() return PythonSingleton::get()->currentInterpreter()->m_module->PyExc_SystemExit; } +PyObject* PyExc_TypeError() +{ + return PythonSingleton::get()->currentInterpreter()->m_module->PyExc_TypeError; +} + PyObject* PyType_Type() { return PythonSingleton::get()->currentInterpreter()->m_module->PyType_Type; @@ -884,4 +903,15 @@ bool IsPy3() return PythonSingleton::get()->currentInterpreter()->m_module->isPy3; } +int PyString_Check(PyObject *o) +{ + return PythonSingleton::get()->currentInterpreter()->m_module->PyObject_IsInstance(o, + PythonSingleton::get()->currentInterpreter()->m_module->PyString_Type ); +} + +int PyUnicode_Check(PyObject *o) +{ + return PythonSingleton::get()->currentInterpreter()->m_module->PyObject_IsInstance(o, + PythonSingleton::get()->currentInterpreter()->m_module->PyUnicode_Type ); +} diff --git a/pykd_ext/version.h b/pykd_ext/version.h index d026650..f8d446a 100644 --- a/pykd_ext/version.h +++ b/pykd_ext/version.h @@ -3,7 +3,7 @@ #define PYKDEXT_VERSION_MAJOR 2 #define PYKDEXT_VERSION_MINOR 0 #define PYKDEXT_VERSION_SUBVERSION 0 -#define PYKDEXT_VERSION_BUILDNO 11 +#define PYKDEXT_VERSION_BUILDNO 12 #define __VER_STR2__(x) #x #define __VER_STR1__(x) __VER_STR2__(x)