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
Set to NEW It looks like EasyHack
I submitted a WiP patch to this: https://gerrit.libreoffice.org/c/core/+/174826 Following the code pointer in https://bugs.documentfoundation.org/show_bug.cgi?id=147377 to change to libffi. I don't know if I am in the right direction. I couln't figure out how to add libffi to the Library_sb in the basic folder. I saw libffi is conditionally declared in multiple make files in external/python3.