https://bugs.documentfoundation.org/show_bug.cgi?id=147377
Bug ID: 147377
Summary: Reimplement SbiDllMgr::Call using libffi
Product: LibreOffice
Version: unspecified
Hardware: All
OS: All
Status: UNCONFIRMED
Severity: enhancement
Priority: medium
Component: BASIC
Assignee: [email protected]
Reporter: [email protected]
CC: [email protected], [email protected]
Currently Basic's Declare statement [1] is implemented in
basic/source/runtime/dllmgr*.cxx using home-grown marshaling code [2]. This
poses several problems:
1. The code is platform-specific (requires separate maintenance per platform),
with much duplication.
2. It has limitation to 20 arguments (see [3]).
3. Calls using non-default calling convention are not implemented (and would
require much work) - so e.g. CDecl keyword is not implemented on Win32, where
it makes sense.
There is libffi [4] that solves exactly this problem. Using it instead of
home-grown code to call external DLL functions would allow to unify the code
across platforms (and implement it where it isn't implemented); avoid any
argument count limitations; define calling convention.
The library uses MIT license; it is already used in LO codebase (it is a
requirement for Python), so it only needs to be linked to Library_sb to be
usable there. Then the code could look similar to
> std::vector<ffi_type*>arg_types;
> std::vector<void*>arg_values;
> std::vector<char> blob;
> if (arguments)
> {
> arg_types.reserve(arguments->Count());
> arg_values.reserve(arguments->Count());
> blob.reserve(arguments->Count() * 8);
>
> for (sal_uInt32 i = 1; i < arguments->Count(); ++i)
> {
> // Put argument values to blob, store pointers to them
> // in arg_values, and their types in arg_types
> }
> }
>
> ffi_type* ret_t = SbxDataType_to_ffi_type(result.GetType());
> ffi_abi eAbi = GetAbi(); // e.g., FFI_DEFAULT_ABI or FFI_MS_CDECL
>
> // Prepare the ffi_cif structure.
> ffi_cif cif;
> if (ffi_status status = ffi_prep_cif(&cif, eAbi, 2, ret_t,
> arg_types.data());
> status != FFI_OK)
> {
> // Handle the ffi_status error.
> }
>
> // Invoke the function.
> ffi_arg retval;
> ffi_call(&cif, FFI_FN(proc.proc), &retval, arg_values.data());
> // ...
(sketched after [5]).
[1] https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03090403.html
[2]
https://opengrok.libreoffice.org/search?&defs=SbiDllMgr%3A%3ACall&project=core
[3]
https://ask.libreoffice.org/t/passing-arrays-in-basic-works-with-excel-error-73-in-libreoffice/48267
[4] https://sourceware.org/libffi/
[5] https://linux.die.net/man/3/ffi_call
--
You are receiving this mail because:
You are the assignee for the bug.