Как я могу реализовать взаимодействие между OCaml и С++?

Я хочу создать мост между OCaml и С++. Например, я хочу использовать некоторые конструкции, написанные в OCaml в С++.

Как я могу это достичь? Существуют ли библиотеки, привязки для этого?

Ответ 1

Вы должны прочитать соответствующую часть руководства по языку: Взаимодействие C с OCaml. Это довольно подробно, даже если, по своей природе, болезненно низкоуровневое.

Если вам не нужна тесная связь между кодом С++ и OCaml (например, вы используете интерфейс GUI и код вычисления, но интенсивное вычислительное ядро ​​вашего приложения не пересекает границы приложений или, по крайней мере, стоимость связи ожидается чтобы быть пренебрежимым по сравнению с временем, проведенным с обеих сторон), я бы рекомендовал вам изучить более простые способы, в которых код С++ и OCaml запускается в отдельных процессах, и обмениваться информацией посредством передачи сообщений (в любом формате, который наиболее удобен для определения: text, s-выражения, двоичный формат, JSON и т.д.). Я бы только попытался скрыть код в том же процессе, если я уверен, что более простой подход не может работать.

Изменить: поскольку я написал этот ответ в прошлом году, появилась библиотека Ctypes, от Джереми Яллопа; это очень перспективный подход, который может быть значительно проще, чем прямое взаимодействие C с OCaml.

Ответ 2

Самый простой способ сделать это - в два этапа: OCaml → C, а затем C → С++ с использованием ключевого слова extern. Я делаю это подробно в проекте COH * ML, который связывает OCaml с Coherence на С++. Например, в OCaml у меня есть:

type coh_ptr  (* Pointer to a Cohml C++ object *)
external coh_getcache: string -> coh_ptr = "caml_coh_getcache"

Затем в С++ сначала функция C:

extern "C" {
  value caml_coh_getcache(value cn) {
    CAMLparam1(cn);
    char* cache_name = String_val(cn);
    Cohml* c;
    try {
      c = new Cohml(cache_name);
    } catch (Exception::View ce) {
      raise_caml_exception(ce);
    }
    value v = caml_alloc_custom(&coh_custom_ops, sizeof(Cohml*), 0, 1);
    Cohml_val(v) = c;
    CAMLreturn(v);
  }
}

И, наконец, реализация С++:

Cohml::Cohml(char* cn) {
  String::View vsCacheName = cn;
  hCache = CacheFactory::getCache(vsCacheName);
}

Переход в другую сторону - это в основном тот же принцип.