Ocaml -> .so -> Golang - PullRequest
       101

Ocaml -> .so -> Golang

0 голосов
/ 20 марта 2020

Я студент и работаю над проектом, в котором мне нужно использовать код, написанный на ocaml. Я хочу написать проект, используя Go. Чтобы понять, как перенести код из ocaml, я решил написать hello world - приложение с таким кодом:

hello.ml:

let print_hello =
  print_endline "Hello World";;

let () =
  Callback.register "Hello callback" print_hello;
;;

Далее я использовал дюну opam для создания разделяемая библиотека (`* .so):

$ dune build hello.so

В соответствии с этим topiс я пытаюсь вызвать функцию из lib с помощью cgo:

main.go:

package main
/*
#cgo LDFLAGS: -ldl

#include <stdlib.h>
#include <dlfcn.h>

typedef int (*someFunc) ();

void bridge_someFunc(someFunc f) {
    f();
}
*/
import "C"
import (
    "unsafe"
)

func main() {
    libpath := C.CString("./hello.so")
    defer C.free(unsafe.Pointer(libpath))
    imglib := C.dlopen(libpath, C.RTLD_LAZY)
    if imglib != nil {
        fHello := C.CString("Hello callback")
        defer C.free(unsafe.Pointer(fHello))
        fp := C.dlsym(imglib, fHello)
        if fp != nil {
            C.bridge_someFunc(C.someFunc(fp))
        }
        C.dlclose(imglib)
    }
}

И это не работает. Что я делаю неправильно? Есть ли другие способы?

1 Ответ

1 голос
/ 27 марта 2020

Вы не можете просто вызывать функции OCaml из C / Go / Rust / любого другого языка. OCaml имеет свои собственные типы данных и соглашение о вызовах. Поэтому вам нужно написать некоторый клейкий код , который переводит C структуры данных в OCaml и наоборот. Это нетривиальная и подверженная ошибкам задача, требующая некоторого опыта работы с OCaml и глубокого понимания внутренних возможностей OCaml. Существует библиотека CTypes , которая позволяет писать этот клейкий код в OCaml вместо C, что менее подвержено ошибкам и намного проще, но все же требует некоторого понимания OCaml.

...