У меня есть классы С++ в следующем формате (копирование только важных частей):
class my_stringimpl {
public:
static sample_string* create(const char* str, int len) {
my_stringimpl* sample = static_cast<my_stringimpl*>(malloc(sizeof(my_stringimpl) + len*sizeof(char)));
char* data_ptr = reinterpret_cast<char*>(sample+1);
memset(data_ptr, 0, len);
memcpy(data_ptr, str, len);
return new (sample) my_stringimpl(len);
}
private:
int m_length;
};
class my_string {
public:
my_string(const char* str, int len)
: m_impl(my_stringimpl::create(str, len)) { }
~my_string() {
delete m_impl;
}
private:
my_stringimpl* m_impl;
};
Для этого класса my_string я добавляю красивый принтер. Я добавил следующие определения в скрипт Python (который я включаю в свой файл .gdbinit) — просто скопированные здесь определения функций:
def string_to_char(ptr, length=None):
error_message = ''
if length is None:
length = int(0)
error_message = 'null string'
else:
length = int(length)
string = ''.join([chr((ptr + i).dereference()) for i in xrange(length)])
return string + error_message
class StringPrinter(object):
def __init__(self, val):
self.val = val
class StringImplPrinter(StringPrinter):
def get_length(self):
return self.val['m_length']
def get_data_address(self):
return self.val.address + 1
def to_string(self):
return string_to_char(self.get_data_address(), self.get_length())
class MyStringPrinter(StringPrinter):
def stringimpl_ptr(self):
return self.val['m_impl']
def get_length(self):
if not self.stringimpl_ptr():
return 0
return StringImplPrinter(self.stringimpl_ptr().dereference()).get_length()
def to_string(self):
if not self.stringimpl_ptr():
return '(null)'
return StringImplPrinter(self.stringimpl_ptr().dereference()).to_string()
Но при использовании я получаю следующую ошибку:
Python Exception <class 'gdb.error'> Cannot convert value to int.:
Если я попытаюсь изменить значение в 'ptr' на int, а затем выполнить артиметику перед возвратом к char (как в определении выше), это даст следующую ошибку:
Python Exception <type 'exceptions.AttributeError'> 'NoneType' object has no attribute 'cast':
Кто-нибудь может сказать, что я делаю неправильно? Я действительно поражен здесь. :(. В двух словах, я пытаюсь добиться следующего эквивалента expr c/С++,
*(char*){hex_address}
в питоне. Как мне это сделать?