[0.3.x] added : typedVar.method ( return function object )

git-svn-id: https://pykd.svn.codeplex.com/svn@91075 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\ussrhero_cp 2016-12-03 20:47:47 +00:00 committed by Mikhail I. Izmestev
parent c0cfd5f666
commit eac07d8add
5 changed files with 68 additions and 132 deletions

View File

@ -932,6 +932,8 @@ BOOST_PYTHON_MODULE( pykd )
"Return list of tuple ( filedName, fieldOffset, fieldValue )" )
.def( "fieldName", TypedVarAdapter::getElementName,
"Return name of struct field by index" )
.def("method", TypedVarAdapter::getMethodByName,
"Return method of class as an object attribute" )
.def("deref",TypedVarAdapter::deref,
"Return value by pointer" )
.def("type", TypedVarAdapter::getType,

View File

@ -126,5 +126,34 @@ python::list TypedVarAdapter::getElementsDir(kdlib::TypedVar& typedVar)
///////////////////////////////////////////////////////////////////////////////
kdlib::TypedVarPtr TypedVarAdapter::getFieldAttr(kdlib::TypedVar& typedVar, const std::wstring &name)
{
{
AutoRestorePyState pystate;
try
{
return typedVar.getElement( name );
}
catch (kdlib::TypeException&)
{}
try
{
return typedVar.getMethod( name );
}
catch (kdlib::TypeException&)
{}
}
std::wstringstream sstr;
sstr << L"typed var has no field " << L'\'' << name << L'\'';
throw AttributeException(std::string(_bstr_t(sstr.str().c_str())).c_str());
}
///////////////////////////////////////////////////////////////////////////////
} // namesapce pykd

View File

@ -109,19 +109,7 @@ struct TypedVarAdapter {
return typedVar.getElement( name );
}
static kdlib::TypedVarPtr getFieldAttr(kdlib::TypedVar& typedVar, const std::wstring &name)
{
try
{
return getField(typedVar, name);
}
catch (kdlib::DbgException&)
{
std::wstringstream sstr;
sstr << L"typed var has no field " << L'\'' << name << L'\'';
throw AttributeException(std::string(_bstr_t(sstr.str().c_str())).c_str());
}
}
static kdlib::TypedVarPtr getFieldAttr(kdlib::TypedVar& typedVar, const std::wstring &name);
static size_t getElementCount( kdlib::TypedVar& typedVar )
{
@ -141,6 +129,12 @@ struct TypedVarAdapter {
return typedVar.getElement( index );
}
static kdlib::TypedVarPtr getMethodByName(kdlib::TypedVar& typedVar, const std::wstring &name)
{
AutoRestorePyState pystate;
return typedVar.getMethod(name);
}
static std::wstring print( kdlib::TypedVar& typedVar )
{
AutoRestorePyState pystate;

View File

@ -162,135 +162,31 @@ python::list TypeInfoAdapter::getElementDir(kdlib::TypeInfo &typeInfo)
python::object callTypedVar(kdlib::TypedVarPtr& funcobj, python::tuple& args)
{
kdlib::NumVariant retVal;
size_t argCount = python::len(args);
if ( argCount != funcobj->getType()->getElementCount() )
throw kdlib::TypeException(L"wrong argument count");
size_t argCount = python::len(args);
kdlib::TypedValueList argLst;
for ( size_t i = 0; i < argCount; ++i )
{
kdlib::TypeInfoPtr argType = funcobj->getType()->getElement(i);
python::object arg = args[i];
if ( argType->isBase() )
python::extract<kdlib::TypedVarPtr> getTypedVar(args[i]);
if ( getTypedVar.check() )
{
kdlib::NumVariant var= NumVariantAdaptor::convertToVariant(arg);
if ( argType->getName() == L"Char" )
{
argLst.push_back( var.asChar() );
}
else if ( argType->getName() == L"WChar" )
{
argLst.push_back( var.asShort() );
}
else if ( argType->getName() == L"Int1B" )
{
argLst.push_back( var.asChar() );
}
else if ( argType->getName() == L"UInt1B" )
{
argLst.push_back( var.asUChar() );
}
else if ( argType->getName() == L"Int2B" )
{
argLst.push_back( var.asShort() );
}
else if ( argType->getName() == L"UInt2B" )
{
argLst.push_back( var.asUShort() );
}
else if ( argType->getName() == L"Int4B" )
{
argLst.push_back( var.asLong() );
}
else if ( argType->getName() == L"UInt4B" )
{
argLst.push_back( var.asULong() );
}
else if ( argType->getName() == L"Int8B" )
{
argLst.push_back( var.asLongLong() );
}
else if ( argType->getName() == L"UInt8B" )
{
argLst.push_back(var.asULongLong());
}
else if ( argType->getName() == L"Long" )
{
argLst.push_back( var.asLong() );
}
else if ( argType->getName() == L"ULong" )
{
argLst.push_back( var.asULong() );
}
else if ( argType->getName() == L"Bool" )
{
argLst.push_back( var.asChar() );
}
else if ( argType->getName() == L"Float" )
{
argLst.push_back( var.asFloat() );
}
else if ( argType->getName() == L"Double")
{
argLst.push_back( var.asDouble() );
}
else
{
throw kdlib::TypeException( std::wstring(L"unsupported argument type ") + argType->getName() );
}
argLst.push_back( getTypedVar() );
continue;
}
else if ( argType->isPointer() )
python::extract<kdlib::NumBehavior> getNumVar(args[i]);
if ( getNumVar.check() )
{
kdlib::MEMOFFSET_64 addr;
python::extract<kdlib::NumBehavior> getNumVar(arg);
python::extract<unsigned long long> getLongLong(arg);
python::extract<long> getLong(arg);
if ( getNumVar.check() )
{
kdlib::NumVariant var = getNumVar();
addr = var.asULongLong();
}
if ( getLongLong.check() )
{
addr = getLongLong();
}
else if ( getLong.check() )
{
addr = getLong();
}
else
{
std::wstringstream sstr;
sstr << "failed to convert " << i << " argument to pointer";
throw kdlib::TypeException(sstr.str() );
}
switch ( argType->getPtrSize() )
{
case 4:
argLst.push_back( static_cast<unsigned long>(addr) );
break;
case 8:
argLst.push_back( static_cast<unsigned long long>(addr) );
break;
default:
throw kdlib::TypeException(L"unsupported call argument");
}
}
else
{
throw kdlib::TypeException(L"unsupported argument type");
kdlib::NumVariant var = getNumVar();
argLst.push_back( var );
continue;
}
kdlib::NumVariant var= NumVariantAdaptor::convertToVariant(args[i]);
argLst.push_back( var );
}
{

View File

@ -388,4 +388,19 @@ class TypedVarTest( unittest.TestCase ):
functype.append("arg2", pykd.baseTypes.Long)
self.assertEqual( 500 / 25, pykd.callFunctionByAddr(functype, target.module.offset("StdcallFuncRet"), 25, 500 ) )
def testCallFunctionWithTypedVar(self):
funcptr = target.module.typedVar("StdcallFuncRet");
ucharVar = target.module.typedVar( "ucharVar" );
self.assertEqual( 10, ucharVar )
self.assertEqual( 200000/10, funcptr( ucharVar, pykd.numVariant(200000) ) )
def testCallWithWrongArgs(self):
self.assertRaises( pykd.TypeException, target.module.typedVar("StdcallFuncRet"), *(1,) )
self.assertRaises( pykd.TypeException, target.module.typedVar("StdcallFuncRet"), *(1,2,3) )
self.assertRaises( pykd.TypeException, target.module.typedVar("StdcallFuncRet"), *(10, target.module.typedVar("g_classChild") ))
def testCallMethod(self):
g_classChild = target.module.typedVar("g_classChild")
self.assertEqual( 1000*5, g_classChild.childMethod(10) )