Windows: lib import/export macros #480
Labels
No labels
3rdparty
Android
API
Author does not respond
bsd
bug
build system/CI
ci-virtual-device
CMake
Contributions Welcome
Core
dependencies
device-specific
documentation
don't_merge
duplicate
enhancement
Example
Haiku
hidraw
hotplug
info required
invalid
libusb
macOS
Misc
Not an issue
question
Release
Test
Test GUI
Windows
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-libusb/hidapi#480
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
github.com/libusb/hidapi@2b70208fea/hidapi/hidapi.h (L33)This does not make sense.
dllexportis normally always used in combination withdllimport(https://learn.microsoft.com/en-us/cpp/cpp/dllexport-dllimport)."does not make" doesn't mean it is broken.
I remember 0 complains about this part.UPD: there are issues - more details below.And I personally use HDIAPI both as a shared and as a static library on multiple platforms, including Windows.
Please share a specific use-case where the old behavior has compilation/runtime issues. If there is such - we'll try to find a backward-compatible solution for all build systems.
I never claimed that errors occur. But I can also argue the other way around, that just because you haven't had an error yet, it doesn't always have to work. After all, the Windows API provides for the combination of
dllimportanddllexport. This is a general improvement suggestion to make the code cleaner. Many libraries like Boost (https://github.com/boostorg/system/blob/develop/include/boost/system/config.hpp) use this kind of macro mechanism to implement the Windows API correctly.You're perfectly right about how things should be in the ideal world.
And I'm definitely considering making it right for HIDAPI v1+.
But right now - my strong position is: "don't try to fix what is not broken". And the #480 breaks all windows builds on our CI.
And our CI is the kind of "golden sample" for those who seek to start using HIDAPI or a reflection of how HIDAPI is already used by many others.
For what it's worth, I did have problems with that. I linked HIDAPI statically into my DLL, and then noticed that all of its functions were accessible and visible with for example
dumpbin /exports. Then I looked at the header and saw that there was no way to disable that, so I just copied the header to my project and edited out the dllexport. Now I am planning on using the hidapi Rust crate, which uses this repo as a submodule, and I realized I'll have to fork this repo and then fork the crate repo to make this same change. That#ifndef HIDAPI_STATICguard would simplify this a lot.As for the dllimport, Microsoft says it's optional, and only serves to make the compiler generate "more efficient" code, whatever that means (source). So maybe it's not worth it if it is a breaking change. Maybe change the
ifdefto anifndef? Then for most people it changes nothing, and people who want to get that "more efficient" code can just define the symbol.That is a very good case.
To be able to workaround cases like that I suggest:
and a corresponding define for CMake build of the static library
that is not perfect (not even close) but should be good-enough for
v0Maybe not the most intuitive, but at least it gives users more flexibility to do what they need without having to change the code itself, and doesn't break anything that currently works. I'd say it's a decent enough compromise.
Hi @Youw ,
I have a similar use case of HIDAPI as @YgorSouza 's.
On my end,
target_compile_definitions(hidapi_winapi PUBLIC HID_API_EXPORT)in \windows\CMakeLists.txt results inHID_API_EXPORTbeing defined as1, causing every function declaration in hidapi.h resulting inerror C2059: syntax error : 'constant'during compilation. Not sure if you guys ever ran into this problem?Maybe something like
target_compile_definitions(hidapi_winapi PUBLIC HID_API_STATIC)in \windows\CMakeLists.txt, andin hidapi.h would be nice?
Very interesting. I haven't seen a compiler that would do somehting like that.
And one of the onces on our CI behaves that way.
And only now I took attention into CMake documentation that actually describes that behavior:
Care to share your compiler and its version?
Just out of my curiosity.
Yes, I guess that should work.
Maybe a little less flexible solution (as it doesn't give the ability to define
HID_API_EXPORTto something else (e.g.__attribute__((visibility("default")))), but as a solution to this problem - more than acceptible.Have a look at https://github.com/OGRECave/ogre-next/blob/master/OgreMain/include/OgrePlatform.h as a full example for static and dynamic with export and import.
A summary is available at https://github.com/Framstag/libosmscout/blob/master/libosmscout/include/osmscout/CoreImportExport.h.
Even in the GCC documentation the usage is documented like this https://gcc.gnu.org/wiki/Visibility.
The original idea of the proposal was to adapt the import-export API correctly for all cases (static, export, import). Since the simple macro solution is apparently still very unpopular, there is a second way. Simply remove the macro completely and supply a module definition file (https://learn.microsoft.com/en-us/cpp/build/reference/module-definition-dot-def-files?view=msvc-170) for Windows. In CMake it is then relatively simple, everything is identical, only under the Windows DLL this file must be passed to the compiler. The disadvantage of this way is that it only works with Visual Studio and clang under Windows. GCC cannot do this. If you really want to support all compilers in all directions, then you should implement the macro variant.
I am aware of the the "perfect" solution using macros.
My position about this stands: until v1 - all changes has to be backward compatible with existing usages of HIDAPI (current CI maybe not perfect - but good-enough example of such).
And no changes to autotools - those are deprecated, and should stay untouched until removed in v1 (unless obvious bugs, which I'm not aware of).
@Youw , my cl version is 14.29.30133, came with Visual Studio 2019 Professional.
My bad I was just thinking of a quick fix and didn't give it a thorough enough thought, I'm sure you would come up with a better way to handle this issue at V1 release, looking forward to it!
I hadn't tested until now, since I haven't touched this part of my code in a while, but indeed I got the same problem. One solution is to define the macro to something explicitly, so it doesn't get implicitly set to 1. This is done in the other empty definitions in the header file itself.
The only thing I don't like about this aproach, that the
/**/would have to be escaped for a specific command prompt/terminal later for compiler to be executed.CMake usually does a decent job doing so, but it has to be done carefully and tested in all environmnets.
I prefer not to pass "weird" symbols into command-line when I can.