Happy case
Using Mingw I have successfully compiled a minimal hello world windows DLL in Ada and used it over the FFI interface:
package MY_FFI is
procedure Hello_World
with
Export => True,
Convention => C,
External_Name => "hello_world";
end MY_FFI;
package body MY_FFI is
procedure Hello_World is
begin
Ada.Text_IO.Put_Line("Hello world!");
end Send_Request;
end MY_FFI;
#[link(name = "my_ffi")]
extern "C" {
#[link_name = "hello_world"]
fn ada_hello_world();
fn my_ffiinit(); // same as adainit just renamed by gprbuild
fn my_ffifinal(); // same as adafinal just renamed by gprbuild
}
pub fn initialize_my_ffi() {
unsafe {
println!("step 1");
my_ffiinit();
println!("step 2");
ada_hello_world();
println!("step 3");
}
}
Which results in:
step 1
step 2
Hello world!
step 3
Real problem
When my Ada library gets more complicated and requires following extra system DLLs:
libgnarl-7.dlllibgnat-7.dlllibgcc_s_seh-1.dll(mingw posix)libwinpthreadthread-1.dll(mingw posix)
I am not able to exactly single out the code, which requires those extra DLLs, but once the code gets complicated enough to require these DLLs, it just stalls in the rust at the my_ffiinit function, outputting only:
step 1
Same code on x64 Linux just works. Also cross-compilation for other Linux platforms (powerpc, arm64) works.
When I use Library_Auto_Init="true", wine64 outputs:
0009:err:module:LdrInitializeThunk "libmy_ffi.dll" failed to initialize, aborting
0009:err:module:LdrInitializeThunk Initializing dlls for L"Z:\\test.exe" failed, status 20474343
Main project gpr:
with "/opt/libA/a_lib.gpr";
with "/opt/libB/b_lib.gpr";
library project MY_FFI is
for Languages use ("Ada");
for Library_Name use "my_ffi";
for Library_Kind use "dynamic";
for Library_Standalone use "encapsulated";
for Source_Dirs use ("src/**");
for Library_Interface use (
"my_ffi",
);
type Target_Type is ("windows64", "windows32", "linux64", "armhf", "powerpc", "arm64");
Target : Target_Type := external ("target", "linux64");
for Library_Dir use "lib/" & external ("target", "linux64");
for Object_Dir use "obj/" & external ("target", "linux64");
end MY_FFI;
gpr for Precompiled shared library A:
library project a_lib is
for Languages use ("Ada");
for Library_Name use "a";
for Library_Kind use "dynamic";
for Source_Dirs use ("src/**");
type Target_Type is ("windows64", "windows32", "linux64", "armhf", "powerpc", "arm64");
Target : Target_Type := external ("target", "linux64");
for Library_Dir use "lib/" & external ("target", "linux64");
for Object_Dir use "obj/" & external ("target", "linux64");
package Naming is
for Spec_Suffix ("ada") use ".ads";
for Body_Suffix ("ada") use ".adb";
for Separate_Suffix use ".adb";
for Casing use "MixedCase";
for Dot_Replacement use "-";
end Naming;
package Compiler is
for Default_Switches ("ada") use ("-fPIC");
end Compiler;
for Externally_Built use "true";
end a_lib;
gpr for library B compiled from the source:
library project b_lib is
for Source_Dirs use ("src");
for Library_Name use "b";
for Library_Dir use "lib";
for Object_Dir use "obj";
for Languages use ("Ada");
package Compiler is
for Switches ("ada") use ("-O2", "-ffunction-sections", "-gnatQ", "-fdata-sections", "-fPIC", "-gnatf", "-gnatwa");
end Compiler;
package Builder is
for Switches ("ada") use ("-j0", "-k", "-s");
end Builder;
type Target_Type is ("windows64", "windows32", "linux64", "armhf", "powerpc", "arm64");
Target : Target_Type := external ("target", "linux64");
for Library_Dir use "lib/" & external ("target", "linux64");
for Object_Dir use "obj/" & external ("target", "linux64");
end b_lib;
Ada.Text_IOis implemented inlibgnat. Have you tried making your library stand-alone? (gprbuild incantation required) - Simon Wrightfor Library_Standalone use "encapsulated";in my gprbuild project file. However my more complicated version of the library is using other Ada shared libraries as dependencies, which do not usefor Library_Standalone use "encapsulated";flag. - Kaarel Allemannencapsulated, so not sure, but the manual says "when encapsulated is used the library can furthermore depend only on static libraries" - Simon Wrightencapsulated. I will format the solution in an answer form as soon as I can. - Kaarel Allemann