Skip to content

Bindings: C

Jon Drobny edited this page Nov 17, 2023 · 14 revisions

C/C++ bindings are also provided by libRustBCA. Pure C bindings can be provided with cbindgen, but the RustBCA.h file automatically generated from cbindgen needs to manually have the math constants (e.g., PI) added, as those don't transliterate directly between Rust and C. Building libRustBCA with:

cargo build --release --lib

Creates the appropriate shared object library, in this case liblibRustBCA.so, or libRustBCA.dll, in target/release/. In the main directory, the header file, RustBCA.h, is located with the function and struct signatures of the C bindings. To use, make sure the RustBCA shared library is accessible to g++. Then, build with: g++ RustBCA.c

If you've built with the python bindings (--features python), include the python libraries to build: g++ RustBCA.c -I/usr/include/python3.8 -lpython3.8

Compound BCA

The preferred C interface function is currently compound_bca_list_c. This function takes one input, InputCompoundBCA, and outputs and has one output, OutputBCA. When using RustBCA functions with C, it is important to, once the output has been processed and used, call the associated cleanup functions, drop_output_tagged_bca and drop_output_bca. Otherwise, memory can leak. These are described below.

OutputBCA compound_bca_list_c(InputCompoundBCA input);

InputCompoundBCA

InputCompoundBCA is for multi-component targets, but one species of incident ion. It has the structure:

struct InputCompoundBCA {
  uintptr_t len;
  /// vx, vy, vz, in m/s
  double (*velocities)[3];
  /// atomic number of incident ions
  double Z1;
  /// atomic mass of incident ions in amu
  double m1;
  /// cutoff energy of incident ions in eV
  double Ec1;
  /// surface binding energy of incident ions in eV
  double Es1;
  /// number of species that make up compound target. >0
  uintptr_t num_species_target;
  /// pointer to array of compound target atomic numbers
  double *Z2;
  /// pointer to array of compound target atomic masses in amu
  double *m2;
  /// pointer to array of compound target atomic number densities in 1/Angstrom^3
  double *n2;
  /// pointer to array of compound target cutoff energies in eV
  double *Ec2;
  /// pointer to array of compound target surface binding energies in eV
  double *Es2;
  /// pointer to array of compound target bulk binding energies in eV
  double *Eb2;
};

Where len is the number of particles, velocities is a list of incident ion velocities, and the material and ion parameters are as stated previously.

OutputBCA

struct OutputBCA {
  /// number of output particles (implanted, reflected, sputtered)
  uintptr_t len;
  /// output particle parameters, energies, and directions
  double (*particles)[9];
};

The output of OutputBCA is these parameters:

len: number of particles in OutputBCA
/// [Z, M, E, x, y, z, ux, uy, uz]: atomic number, atomic mass (amu) energy (eV), position (angstrom), direction

Example of C++ Bindings in Use

RustBCA.c

#include "RustBCA.h"
#include <iostream>
#include <vector>

int main() {
  OutputBCA output;

  double velocities[2][3] = {{500000.0, 0.1, 0.0}, {500000.0, 0.1, 0.0}};
  double Z[1] = {74.0};
  double m[1] = {184.0};
  double n[1] = {0.06306};
  double Ec[1] = {1.0};
  double Es[1] = {8.79};
  double Eb[1] = {0.0};

  InputCompoundBCA input = {
      2,
      velocities,
      1.0,
      1.0,
      1.0,
      1.0,
      1,
      Z,
      m,
      n,
      Ec,
      Es,
      Eb
    };

  //output = simple_bca_c(0., 0., 0., 0.5, 0.5, 0.00, 2000.0, 2.0, 4.0, 1.0, 0.0, 74.0, 184.0, 1.0, 8.79, 0.06306, 0.0);

  output = compound_bca_list_c(input);

  std::cout << "Particle 1 Z: ";
  std::cout << output.particles[0][0];
  std::cout << std::endl;

  std::cout << "Particle 1 E [eV]: ";
  std::cout << output.particles[0][2];
  std::cout << std::endl;

  std::cout << "Particle 2 Z: ";
  std::cout << output.particles[1][0];
  std::cout << std::endl;

  std::cout << "Particle 2 E [eV]: ";
  std::cout << output.particles[1][2];
  std::cout << std::endl;

  //Clean up memory from RustBCA call
  drop_output_bca(output);

  return 0;
}