1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use libc;
use python3_sys::{METH_VARARGS, Py_BuildValue, PyArg_ParseTuple, PyMethodDef, PyModule_Create, PyModuleDef, PyModuleDef_HEAD_INIT, PyObject, PyCapsule_GetPointer};
use crate::npyffi::{PyArrayObject, NPY_ARRAY_CARRAY, PyArray_Sort};
use core::slice;
use std::os::raw::{c_void};
use std::ptr::null_mut;
use std::time::Instant;

pub mod npyffi;


#[inline]
const fn c_str(value: &str) -> *const libc::c_char {
    value.as_ptr() as *const libc::c_char
}

unsafe extern "C" fn sum_as_string_py(_: *mut PyObject, args: *mut PyObject) -> *mut PyObject {
    let a: i64 = 0;
    let b: i64 = 0;
    if PyArg_ParseTuple(args, c_str("ii\0"), &a, &b) == 0 {
        return 0 as *mut _;
    }
    println!("Values after: {0}, {1}", a, b);
    let result: f64 = (&a + &b) as f64 + 0.1;
    println!("Values result: {0}", result);
    Py_BuildValue(c_str("d\0"), result)
}


unsafe extern "C" fn try_numpy(_: *mut PyObject, args: *mut PyObject) -> *mut PyObject {
    let a: i64 = 0;
    let py_array: *mut PyArrayObject = 0 as *mut PyArrayObject;
    let capsule: *mut PyObject = null_mut();

    println!("Values before: {0}", a);
    if PyArg_ParseTuple(args, c_str("iOO\0"), &a, &py_array, &capsule) == 0 {
        println!("Values return: {0}, {1}", a, a);
        /*if PyArray_Check(py_object_ptr as *mut PyObject) == 0 {
            println!("py array check return: {0}, {1}", a, a);
        }*/
        return null_mut();
    }

    let now = Instant::now();


    let pointer = PyCapsule_GetPointer(capsule, null_mut()) as *const *const c_void;

    let numpy = npyffi::NumpyModuleReference::from(capsule);



    /*
    module.PyArray_Sort(py_array, 0, npyffi::types::NPY_SORTKIND::NPY_QUICKSORT);
    module.PyArray_Sort(py_array, 0, npyffi::types::NPY_SORTKIND::NPY_QUICKSORT);
    */

    let secs = now.elapsed().as_secs_f64();
    println!("secs: {}", secs);

    (numpy.PyArray_Sort)(py_array, 0, npyffi::types::NPY_SORTKIND::NPY_QUICKSORT);
    numpy.PyArray_Sort2(py_array, 0, npyffi::types::NPY_SORTKIND::NPY_QUICKSORT);

    let py_object = *py_array;

    let descr = *py_object.descr;
    let data = py_object.data as *mut i64;

    let sli = slice::from_raw_parts_mut(data, 3);
    println!("len: {}", sli.len());
    for item in sli {
        println!("item: {}", item);
    }

    println!("Values after: {0}, nd={1}, type_={2}", a, py_object.nd, descr.type_num);



    let arr = (numpy.PyArray_New)(numpy.PyArray_Type, 1, py_object.dimensions, 7, 0 as *mut isize, (*py_array).data as *mut c_void, 0, NPY_ARRAY_CARRAY, 0 as *mut _);

    Py_BuildValue(c_str("O\0"), arr)
}

const METHODS: [PyMethodDef; 3] = [
    PyMethodDef {
        ml_name: c_str("sum_as_string\0"),
        ml_meth: Some(sum_as_string_py),
        ml_flags: METH_VARARGS,
        ml_doc: c_str("...\0"),
    },
    PyMethodDef {
        ml_name: c_str("try_numpy\0"),
        ml_meth: Some(try_numpy),
        ml_flags: METH_VARARGS,
        ml_doc: c_str("...\0"),
    },
    PyMethodDef {
        ml_name: 0 as *const libc::c_char,
        ml_meth: None,
        ml_flags: 0,
        ml_doc: 0 as *const libc::c_char,
    }
];

static mut DEFINITION: PyModuleDef = PyModuleDef {
    m_base: PyModuleDef_HEAD_INIT,
    m_name: c_str("_mylibrary\0"),
    m_doc: c_str("...\0"),
    m_size: 0,
    m_methods: METHODS.as_ptr() as *mut _,
    m_slots: 0 as *mut _,
    m_traverse: None,
    m_clear: None,
    m_free: None,
};

pub fn my_function() -> i64 {
    4
}

#[no_mangle]
#[allow(non_snake_case)]
pub unsafe extern "C" fn PyInit__mylibrary() -> *mut PyObject {
    PyModule_Create(&mut DEFINITION)
}

#[cfg(test)]
mod tests {
    use crate::my_function;

    #[test]
    fn it_works() {
        assert_eq!(2 + 2, my_function())
    }
}