简体   繁体   中英

Passing large integers from Python to C/C++ with scipy.weave.inline

I found that a portion of my code written in python could be done faster in C. I used scipy.weave.inline to do this. seek_pos, one of the integers that I needed to pass into my C code, was (at times) larger than what could be represented by a 32 bit long. I could cout seek_pos and get the correct value (maybe 2.3 billion) but when doing other things with it, such as using it as the offset in fseek or fseeko64, it would act as though it were -1.9 billion (or whatever value you'd get from wrapping past the range of positive long ints and around into the negative long ints).

MY WORKAROUND was to break the large integer down in python y=seek_pos/N, x=seek_pos%N, pass in those smaller numbers and rebuild the larger number in C, seek_pos_off = Y*N+X. I"m new to both Weave and C/C++. My code works now but I think this is a pretty ridiculous way of getting there. Maybe I could have specified a premade or made a custom type converter for weave.inline, but how to do this was not clear to me.

If someone can suggest a better way of doing this, I'd appreciate it, but if not, I wanted to post this anyway so that someone dealing with the same problem might at the very least find my work around when searching.

Here's the relevant portion of my code

vtrace = numpy.zeros(len_trace, dtype='short')
c_code = '''
using namespace std;
const char * cc_fpath = filepath.c_str();
FILE * infile;
infile = fopen(cc_fpath, "r");
long seek_pos_off;
long long_multiplier;
long_multiplier = seek_pos_multiplier;
long long_adder;
long_adder = seek_pos_adder;
seek_pos_off = long_multiplier * 2000000000 + long_adder;
fseek(infile, seek_pos_off, SEEK_SET);
for (int n=0; n<len_trace; n++) {
    fread(vtrace+n, data_bytes_per_channel, 1, infile);
    fseek(infile, skip_bytes, SEEK_CUR);
}
fclose(infile);

return_val = 0;
'''
filepath = str(filepath)
seek_pos = int(data_start_pos_in_bytes + start_byte)
seek_pos_multiplier = seek_pos/2000000000
seek_pos_adder = seek_pos%2000000000
weave.inline(c_code, ['vtrace', 'filepath', 'seek_pos_multiplier', 
        'seek_pos_adder', 'len_trace', 'data_bytes_per_channel', 
        'skip_bytes'], headers=['<typeinfo>'])

Have you tried

seek_pos = long(data_start_pos_in_bytes + start_byte)

instead of

seek_pos = int(data_start_pos_in_bytes + start_byte)

That may be it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM