# How can I return a C struct with numba?

**URL:** https://numba.discourse.group/t/how-can-i-return-a-c-struct-with-numba/2427
**Category:** Community Support
**Created:** [February 27, 2024, 7:27pm UTC](https://numba.discourse.group/t/how-can-i-return-a-c-struct-with-numba/2427 "2024-02-27T19:27:02Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![gabrielfougeron](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/gabrielfougeron/32/1003_2.png) [@gabrielfougeron](https://numba.discourse.group/u/gabrielfougeron)
#### Post date: [February 27, 2024, 7:27pm UTC](https://numba.discourse.group/t/how-can-i-return-a-c-struct-with-numba/2427/1 "2024-02-27T19:27:02Z")

</div>

Hi,

I’m using numba in conjunction with scipy.LowLevelCallable to pass small callables to numerical integrators.

The following MWE works as expected. It allows me to jit a parametrized function and return the result as a scipy.LowLevelCallable

```python

import cffi
import numba
from numba.core.typing import cffi_utils
import scipy

numba_kwargs = {
    'nopython':True ,
    'cache':True ,
    'fastmath':True ,
    'nogil':True ,
}

src = """
typedef double (*fun_t)(double) ;
"""

ffi = cffi.FFI()
ffi.cdef(src)

sig = cffi_utils.map_type(ffi.typeof('fun_t'), use_record_dtype=True)

def param_fun(n):

    @numba.cfunc(sig)
    @numba.jit(signature=sig, **numba_kwargs)
    def fun(x):
        return n*x

    return scipy.LowLevelCallable(fun.ctypes)

toto = param_fun(0.5)

```

Now, how can I do the same, but returning a C struct ?

```python
src = """
typedef struct {
  double a;
} a_t;

typedef a_t (*fun_t)(double) ;
"""

ffi = cffi.FFI()
ffi.cdef(src)

sig = cffi_utils.map_type(ffi.typeof('fun_t'), use_record_dtype=True)

def param_fun(n):

    @numba.cfunc(sig)
    @numba.jit(signature=sig, **numba_kwargs)
    def param_fun(x):
        # ?????

        return n*x

    return scipy.LowLevelCallable(param_fun.ctypes)

```

---

<div class="post-metadata">

### Author: ![Oyibo](https://avatars.discourse-cdn.com/v4/letter/o/4af34b/32.png) [@Oyibo](https://numba.discourse.group/u/Oyibo)
#### Post date: [February 28, 2024, 5:40pm UTC](https://numba.discourse.group/t/how-can-i-return-a-c-struct-with-numba/2427/2 "2024-02-28T17:40:07Z")

</div>

Hey @gabrielfougeron ,

If you intend to pass only scalars as additional arguments for a SciPy quadrature, you can define your C structure using `make_c_struct` and utilize the `LowLevelCallable` function.

```auto
import numpy as np
import numba as nb
from numba import types
from scipy import integrate, LowLevelCallable
import ctypes

# Define the C-struct
args_dtype = types.Record.make_c_struct([
    ('x2', types.float64),
])

# function to integrate
def integrand(x1, x2):
    return np.exp(-x1/x2) / x1**2

# function factory
def create_jit_integrand_function(integrand_function, args_dtype):
    jitted_function = nb.njit(integrand_function)

    # double func(double x, void *user_data)
    @nb.cfunc(types.float64(types.float64, types.CPointer(args_dtype)))
    def wrapped(x1, user_data_p):
        user_data = nb.carray(user_data_p, 1)
        x2 = user_data[0].x2
        return jitted_function(x1, x2)
    return wrapped

# wrapped function call
def do_integrate(func, args, a=0, b=1):
    integrand_func = LowLevelCallable(func.ctypes, user_data=args.ctypes.data_as(ctypes.c_void_p))
    # quadrature(func, a, b, args=(), tol=1.49e-8, rtol=1.49e-8, maxiter=50, vec_func=True, miniter=1)
    return integrate.quad(integrand_func, a, b)

# How to use it:
x2 = 1.0
args = np.array((x2,), dtype=args_dtype)
func = create_jit_integrand_function(integrand, args_dtype)
print(do_integrate(func, args, a=1, b=np.inf))
# (0.14849550677592208, 3.8736750296130505e-10)

```

If you need to define arrays as arguments, there is an example by @max9111

> <https://stackoverflow.com/questions/58421549/passing-numpy-arrays-as-arguments-to-numba-cfunc/58561573#58561573>

---

<div class="post-metadata">

### Author: ![gabrielfougeron](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/gabrielfougeron/32/1003_2.png) [@gabrielfougeron](https://numba.discourse.group/u/gabrielfougeron)
#### Post date: [February 29, 2024, 5:05pm UTC](https://numba.discourse.group/t/how-can-i-return-a-c-struct-with-numba/2427/3 "2024-02-29T17:05:21Z")

</div>

Thanks, I did not know about `types.Record.make_c_struct`
