开发者

Access std::complex<> from gdb python macro

开发者 https://www.devze.com 2023-03-21 04:36 出处:网络
I\'m trying to write a python script that evaluates a vector Complex numbers so I can do things like plot it via matplotlib.Python code below with comment where code breaks:

I'm trying to write a python script that evaluates a vector Complex numbers so I can do things like plot it via matplotlib. Python code below with comment where code breaks:

import sys
import gdb 
import matplotlib.pyplot as plt
class Plotter (gdb.Command):
""" Plots vector"""
# _iterator pulled directly from
# /usr/share/gdb/python/libstdcxx/v6/printers.py
class _iterator:
    def __init__ (self, start, finish):
        self.item = start
        self.finish = finish
        self.count = 0

    def __iter__(self):
        return self

    def next(self):
        if self.item == self.finish:
            raise StopIteration
        count = self.count
        self.count = self.count + 1
        elt = self.item.dereference()
        self.item = self.item + 1
        return ('[%d]' % count, elt)

def __init__(self):
    super(Plotter, self).__init__("plot_test", gdb.COMMAND_OBSCURE)
def invoke(self, arg, from_tty):        
    frame = gdb.selected_frame()
    try:
        val = gdb.Frame.read_var(frame, arg)
        if str(val.type).find("vector") != -1:
            print "Plot vector:", str(val.type)
            if (str(val.type).find("complex") != -1):
                self.plot_complex_vector(val)
            else:
                self.plot_vector(val)
        else:
            print "Not a vector..." 

    except:
        print "No such variable:", arg
        return 

def plot_complex_vector(self, val): 
    try:
        it = self._iterator(val['_M_impl']['_M_start'],
                            val['_M_impl']['_M_finish'])
        vector = []
        while(True):
            x = it.next()
            vector.append(complex(x[1])) # doesn't work...
        return

    except StopIteration:
        pass
    except: 
        print sys.exc_info()[0]
    print vector
    plt.plot(vector)
    plt.show()
# works...
d开发者_Go百科ef plot_vector(self, val): 
    try:
        it = self._iterator(val['_M_impl']['_M_start'],
                            val['_M_impl']['_M_finish'])
        vector = []
        while(True):
            x = it.next()
            vector.append(float(x[1]))

    except StopIteration:
        pass
    except: 
        print sys.exc_info()[0]
    print vector
    plt.plot(vector)
    plt.show()                        
    Plotter()

So the question is, how do I access the real/imaginary parts of a a std::complex value?

It looks like doing a

print x[1]

Will print values like : {_M_value = 0 + 1 * I}

Update: It looks like I can do a little string editing before doing a typecast:

while(True):
    x = it.next()
    s = str(x[1]['_M_value'])
    # convert string to complex format that python understands. 
    c = complex(s.replace('I','j').replace(' ','').replace('*',''))
    vector.append(c) # Works now...  

But... is there a better way to do this?


    try:
        it = self._iterator(val['_M_impl']['_M_start'],
                            val['_M_impl']['_M_finish'])
        vector = []
        while(True):
            x = it.next()
            vector.append(complex(x[1])) # doesn't work...
        return

    except StopIteration:
        pass
    except: 
        print sys.exc_info()[0]

Is not how iterators are meant to be used in python. Use

    try:
        it = self._iterator(val['_M_impl']['_M_start'],
                            val['_M_impl']['_M_finish'])
        vector = [complex(x[1]) for x in it]
    except Exception as e: 
        print e, sys.exc_info()[0]

If you really still want to wrap it in a try...except block.

Edit: Try complex(x.real() + x.imag()). What does print x.type.fields() show?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号