HFMU / HaskellFmu

The library package to include in order to develop an FMU with Haskell
Other
1 stars 0 forks source link

Wrap each Foreign Function Declaration #7

Open CThuleHansen opened 5 years ago

CThuleHansen commented 5 years ago

Based on #6. The current approach is to wrap each foreign function declaration of HaskellFMU within the accompanying c-file

See reddit post: (copy below in comment): https://www.reddit.com/r/haskell/comments/apeoev/haskell_ffi_exporting_symbols_from_builddepends/

Functions wrapped:

CThuleHansen commented 5 years ago

I have a haskell LIBRARY project with several export foreign function declarations - we call it LIB.

I then have a haskell (cabal) project, call it X, that depends on LIB. X contains 1 export foreign function declaration.

I compile X to a shared library using cabal native-shared. When I list the symbols of the shared object (nm objname.so) I only see the single foreign func decls from X, and not the ones from LIB. This means, that loading the library from c with:

  handle = dlopen("x.dylib", RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST);

raises segmentation fault when invoking functions from LIB. The reason is the RTLD_FIRST flag, where it is specified, that only symbols from the first image should be available, and not subsequent images (https://github.com/opensource-apple/dyld/blob/3f928f32597888c5eac6003b9199d972d49857b5/doc/man/man3/dlopen.3#L106-L114). (I do not have any options in terms of the dlopen behaviour - it is standardised.)

To experiment, I have renamed a foreign func decl in LIB from "a" to "aa". I have then declared "aa" as extern and implemented "a" in the accompanying C file of X, that does the hs_init and similar setup. I.e.:

fmi2Component fmi2Instantiate(fmi2String a , fmi2Type b, fmi2String c, fmi2String d, const fmi2CallbackFunctions* e, fmi2Boolean f, fmi2Boolean g)
{
  printf("hfmu.c: fmi2instantiate\n");
  return  fmi2Instantiatee(a, b, c, d, e, f, g);
}

and

extern fmi2InstantiateTYPE fmi2Instantiatee;

This works, since X now exports the function "a" instead of LIB. I can of course apply this wrapping to all foreign func decls of LIB, but I am wondering if there is a better approach?

I have tried most, if not all, of the options from: https://cabal.readthedocs.io/en/latest/installing-packages.html?highlight=static#miscellaneous-options