Skip to content

What should C lib API be? #151

@JohnLCaron

Description

@JohnLCaron

Strawman is at core/src/commonMain/kotlin/com/sunya/netchdfc/NetchdfCApi.kt
which generates core/build/bin/linuxX64/releaseShared/libnetchdf_api.h

struct {
    ...
     libnetchdf_kref_kotlin_IntArray (*get_array)(libnetchdf_kref_com_sunya_netchdfc_ArrayIntSection thiz);
     libnetchdf_KInt (*get_nelems)(libnetchdf_kref_com_sunya_netchdfc_ArrayIntSection thiz);
     libnetchdf_kref_kotlin_IntArray (*get_shape)(libnetchdf_kref_com_sunya_netchdfc_ArrayIntSection thiz);
     const char* (*get_varName)(libnetchdf_kref_com_sunya_netchdfc_ArrayIntSection thiz);
     libnetchdf_kref_kotlin_LongArray (*get_varShape)(libnetchdf_kref_com_sunya_netchdfc_ArrayIntSection thiz);
} ArrayIntSection;

libnetchdf_kref_com_sunya_netchdfc_ArrayIntSection (*readArrayIntSection)(
    libnetchdf_kref_com_sunya_cdm_api_Netchdf thiz, 
    libnetchdf_kref_com_sunya_cdm_api_Variable v2, 
    libnetchdf_kref_kotlin_IntArray start, 
    libnetchdf_kref_kotlin_IntArray length
);

libnetchdf_kref_com_sunya_netchdfc_ArrayIntSection (*readArrayInt) (
    libnetchdf_kref_com_sunya_cdm_api_Netchdf thiz, 
     libnetchdf_kref_com_sunya_cdm_api_Variable v2
);

An issue here is that you dont know the length of shape and varShape, unless you look up the variable rank.
The data is returned in pinned memory that the user must free.

Example (core/ctest/main.c):

libnetchdf_kref_com_sunya_cdm_api_Netchdf netchdf = lib->kotlin.root.com.sunya.netchdfc.openNetchdfFile("simple_xy.nc");

libnetchdf_kref_com_sunya_cdm_api_Variable variable = lib->kotlin.root.com.sunya.cdm.api.Netchdf.findVariable(netchdf, "data");

libnetchdf_kref_com_sunya_netchdfc_ArrayIntSection arrayIntSection = lib->kotlin.root.com.sunya.netchdfc.readArrayInt(netchdf, variable);

int nelems = lib->kotlin.root.com.sunya.netchdfc.ArrayIntSection.get_nelems(arrayIntSection);
printf("nelems=%d\n", nelems);

libnetchdf_kref_kotlin_IntArray shapeIntArray = lib->kotlin.root.com.sunya.netchdfc.ArrayIntSection.get_shape(arrayIntSection);
int  *shape = (int *) shapeIntArray.pinned;
printf("first shape=%d\n", *shape);
printf("second shape=%d\n", *(shape+1));

libnetchdf_kref_kotlin_IntArray intarray = lib->kotlin.root.com.sunya.netchdfc.ArrayIntSection.get_array(arrayIntSection);
int *data = (int *) intarray.pinned;

corresponding netcdf-C API is:

https://docs.unidata.ucar.edu/netcdf-c/4.9.3/group__variables.html#gaa109955db46f2dd6bab83ae7d53c7750

int nc_get_vara_int(	
  int	ncid,
  int	varid,
  const size_t *	startp,
  const size_t *	countp,
  int *	ip )

int nc_get_var_int	(
	int	ncid,
        int	varid,
        int *	ip )

here, the user allocates the return array: Example:

#define TIMES 3
#define LATS 5
#define LONS 10
int  status;
int ncid;
int rh_id;
static size_t start[] = {0, 0, 0};
static size_t count[] = {TIMES, LATS, LONS};
double rh_vals[TIMES*LATS*LONS];
   ...
status = nc_open("foo.nc", NC_NOWRITE, &ncid);
if (status != NC_NOERR) handle_error(status);
   ...
status = nc_inq_varid (ncid, "rh", &rh_id);
if (status != NC_NOERR) handle_error(status);
   ...
status = nc_get_vara_double(ncid, rh_id, start, count, rh_vals);
if (status != NC_NOERR) handle_error(status);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions