dt_Handle reaction, container, molecule1, moleculeX;
  dt_String csmi, asmi;
  dt_Integer clen, alen;

  /* Read SMILES in. */
  reaction = dt_smilin(13, "O>>[OH-].[H+]");

  /* Write canonical form. */ 
  csmi = dt_cansmiles(&clen, reaction, 0);
  /* Write abitrary form. */ 
  asmi = dt_arbsmiles(&alen, reaction, 0);

  printf("Canonical form is %.*s and arbitrary form is %.*s.\n",
         clen, csmi, alen, asmi);

  /* Stream the reaction. */
  container = dt_stream(reaction, TYP_MOLECULE);  
  /* The next item gives the first molecule. */
molecule1 = dt_next(container);
if (dt_getrole(molecule1, reaction) == DX_ROLE_REACTANT)
printf("The molecule role is reactant.\n");

/* The next item gives the second molecule */
moleculeX = dt_next(container);
if (dt_getrole(moleculeX, reaction) == DX_ROLE_PRODUCT)
printf("The molecule role is product.\n");

/* The next item is the NULL object. */
moleculeX = dt_next(container);
if (NULL_OB == moleculeX)
printf("The NULL object is next.\n");

/* A reset and next operation gives the first molecule again. */
moleculeX = dt_next(container);
if (moleculeX == molecule1)
printf("Reset is like rewind.\n");

/* Each molecule refers to the reaction as its parent. */
if (dt_parent(molecule1) == reaction)
printf("You can access the reaction through the molecule.\n");

Canonical form is O>>[H+].[OH-] and arbitrary form is O>>[OH-].[H+].
The molecule role is reactant.
The molecule role is product.
The NULL object is next.
Reset is like rewind.
You can access the reaction through the molecule.