I’m one of the maintainers of gpgme-sharp, a library that provides GPGME bindings for C#. I had a few questions about the GPGME DLL:
I noticed a DLL at C:\Program Files (x86)\Gpg4win\bin_64\libgpgme6-11.dll that seems to be undocumented. This appears to be a 64-bit version of libgpgme-11.dll. Does the 6 in the name just signify that it’s 64-bit, or is there a deeper meaning there?
Which version of Gpg4Win added this DLL (since I don’t remember it being there in the past)?
Does the Gpg4Win installer write a registry key (or other configuration entry) with the path to Gpg4Win (e.g. C:\Program Files (x86)\Gpg4win\) that we can use to locate the DLLs if they’re not in the default location of %ProgramFiles(x86)\Gpg4Win\?
Would I be allowed to bundle libgpgme-11.dll and libgpgme6-11.dll with gpgme-sharp, or do I need to require that users install Gpg4Win manually (which is the current state today)? On Linux we just rely on libgpgme.so.11 being present on the system.
Would I be allowed to bundle libgpgme-11.dll and libgpgme6-11.dll with gpgme-sharp,
It is possible if the conditions of the Free Software licenses are fulfilled. GPGME is under LGPL-2.1-or-later and GnuPG itself, which you would also need is under GPL-3.0-or-later.
While it is possible from the licensing side, it maybe better for updating if the original Gpg4win packages were used.
I have a question about the libgpgme6-11.dll file. I’m not sure if it is a 64-bit version, because when I try to link it from x64, I get a warning that x86 is not compatible with x64.
Also, I noticed that the LibGpgError file does not have the same extension as 6-11.dll.
Could you please explain how you managed to link it correctly? I would appreciate your help.
I have also posted this issue on the forum (with a link to working x86 CMakeList, and a project of c++ RAII wrap for this library we can test on):
I’m using P/Invoke in C# and don’t get compilation errors and it works well at runtime on a 64-bit system, but I’m not sure how importing native libraries differs between C# and C++.
In C# you write the call signature manually, for example:
and I don’t think the linker is involved. C# is generally JIT compiled so the compiler only compiles it to architecture-independent bytecode, then at runtime it compiles to machine code and optimizes it for the architecture + processor it’s running on. C# apps are generally compiled as “Any CPU” which means the same EXE works on both 32-bit and 64-bit machines (thanks to JIT compiling). C# does support AoT (Ahead of Time) compilation now, but I’ve not tested the gpgme-sharp library with it.
As for finding the DLL… In my C# code, I have a list of paths that it looks for - first checking the registry then falling back to a hard-coded %ProgramFiles(x86)%\Gpg4Win:
This is used with a custom DLL resolver (.NET feature NativeLibrary.SetDllImportResolver) that loads the correct DLL based on if the process is 32-bit or 64-bit. Essentially it’s like using Win32 LoadLibrary and GetProcAddress.
Thank you, I now realize that linking in C# and C++ is very different and that you had to use extern with all the C functions. Unfortunately, even if I could Win32 LoadLibrary in C++ Windows, which might fix the compatibility issue, it would be too hard for me to manage the memory correctly on the caller side in C, and that is beyond my abilities.
I saw your successful attempt to load the pgpme dll in C# at runtime, and I wanted to try it myself using boost:dll. However, it did not work for me. I could load other system dlls, but the gpgme dll failed with an incompatibility error.