> On Aug 10, 2020, at 3:27 PM, Mark Adams <[email protected]> wrote:
> 
> I had some problems giving a container an PETSc object so I wrapped it in a 
> struct. 
> I forget what problem I had. Maybe ISColoringDestroy can't take a void*.
> I'd like to check if I was just missing something. 
> Should something like this work?
> 
>     ISColoring c;
>     ....
>     ierr = PetscContainerSetPointer(container,(void*)c);CHKERRQ(ierr);
>     ierr = PetscContainerSetUserDestroy(container, 
> ISColoringDestroy);CHKERRQ(ierr);

  Mark

   ISColoring is a plain old C struct: 

struct _n_ISColoring {
  PetscInt        refct;
...

so it seems like this should work. But ISColoringDestroy(), like most PETSc 
destroy functions, takes the address of the pointer as the argument (as opposed 
to the pointer itself, this is so XXXDestroy() can set the pointer to null to 
prevent it getting used again accidentally with a now meaningless value.) So 
there is a disconnect in how PETSc handles destroying objects (take the address 
of a pointer) and the pointer for containers (take a pointer). Looking back I 
just made the container concept as simple as possible and did not think about 
the API difference. We could fix it now but it might break a tiny bit of user 
code.

This should work

static PetscErrorCode MyISColoringDestroy(void *is)
{
   ISColoring tmp = (ISColoring)is;
   return ISColoringDestroy(&tmp);
}

ierr = PetscContainerSetUserDestroy(container, 
MyISColoringDestroy);CHKERRQ(ierr);

then you won't need the dummy struct.

Barry



Reply via email to