-
-
Notifications
You must be signed in to change notification settings - Fork 212
PluggableUSBModule::getProductVersion() not defined #130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@tttapa thanks for pointing that out! I didn't think there were any other module in development when I pushed it so I took the freedom to make a breaking change, my bad. |
@facchinm no problem, it's easy enough to fix :) I've opened a pull request with the proposed change. When the method is not implemented in a derived PluggableUSBModule, you now get a clear compiler message instead of a linker error:
instead of
It seems to be common in the ARM mbed os code, and you might already be aware of this, but one thing I noticed while trying to understand the PluggableUSB code is that none of the virtual methods are marked For example: class USBCDC: public internal::PluggableUSBModule{
virtual const uint8_t *string_iproduct_desc();
}; This implies to me that class USBCDC: public internal::PluggableUSBModule{
const uint8_t *string_iproduct_desc() override;
}; You can use the compiler to tell you which methods should be marked
|
Closing as fixed by #148 . |
Issue arduino#130 correctly identifies a newly-added method as pure virtual and fixes the declaration. However, for some reason it didn't address all of the other virtual methods in that same class (`PluggableUSBModule`) that do not define a default implementation. The only virtual method that has a default implementation is provided inline in the class interface: ```c++ virtual void callback_reset() {}; ``` These issues combined prevent the compiler from being able to emit a vtable for the `PluggableUSBModule` class, thus preventing users from correctly subclassing it or any one of its derived classes such as `USBCDC`, `USBHID`, `USBMIDI`, etc. Refer to the following answer on StackOverflow for a detailed explanation of the issue: https://stackoverflow.com/a/57504289/1054397 This PR adds the pure specifier (`= 0`) to all of the virtual methods in this class that do not have a default implementation. It also moves the default empty definition of `virtual void callback_reset()` to the class definition in `USB/PluggableUSBDevice.cpp` so that this class complies completely with the criteria for emitting a vtable. > #### Note > > The error that I was encountering prior to these changes was pretty > cryptic (from PlatformIO): > > ```txt > .pio/build/hid/src/target.cpp.o: In function `foo()': > USBHID/src/PluggableUSBHID.h:53: undefined reference to > `vtable for arduino::internal::PluggableUSBModule' > .pio/build/hid/src/target.cpp.o: In function `foo()': > foo.hpp:100: undefined reference to > `vtable for arduino::internal::PluggableUSBModule' > collect2: error: ld returned 1 exit status > *** [.pio/build/hid/firmware.elf] Error 1 > ``` > > Even stranger, the error would only be generated with a debug build; > i.e., the only difference in command-line arguments was the additional > CFLAGS of `-Og -g2 -ggdb2`. Without the debug flags, my project was > building without error. > > With the changes in this PR, my project now builds with and without > these additional debug flags. Further verification was performed by > testing the example sketches `Keyboard`, `KeyboardRaw`, and `Mouse` > from library `USBHID` as well as using the core `Serial` object for > ordinary USB serial I/O (`USBCDC`).
Issue arduino#130 correctly identifies a newly-added method as pure virtual and fixes the declaration. However, for some reason it didn't address all of the other virtual methods in that same class (`PluggableUSBModule`) that do not define a default implementation. The only virtual method that has a default implementation is provided inline in the class interface: ```c++ virtual void callback_reset() {}; ``` These issues combined prevent the compiler from being able to emit a vtable for the `PluggableUSBModule` class, thus preventing users from correctly subclassing it or any one of its derived classes such as `USBCDC`, `USBHID`, `USBMIDI`, etc. Refer to the following answer on StackOverflow for a detailed explanation of the issue: https://stackoverflow.com/a/57504289/1054397 This PR adds the pure specifier (`= 0`) to all of the virtual methods in this class that do not have a default implementation. It also moves the default empty definition of `virtual void callback_reset()` to the class definition in `USB/PluggableUSBDevice.cpp` so that this class complies completely with the criteria for emitting a vtable. > #### Note > > The error that I was encountering prior to these changes was pretty > cryptic (from PlatformIO): > > ```txt > .pio/build/hid/src/target.cpp.o: In function `foo()': > USBHID/src/PluggableUSBHID.h:53: undefined reference to > `vtable for arduino::internal::PluggableUSBModule' > .pio/build/hid/src/target.cpp.o: In function `foo()': > foo.hpp:100: undefined reference to > `vtable for arduino::internal::PluggableUSBModule' > collect2: error: ld returned 1 exit status > *** [.pio/build/hid/firmware.elf] Error 1 > ``` > > Even stranger, the error would only be generated with a debug build; > i.e., the only difference in command-line arguments was the additional > CFLAGS of `-Og -g2 -ggdb2`. Without the debug flags, my project was > building without error. > > With the changes in this PR, my project now builds with and without > these additional debug flags. Further verification was performed by > testing the example sketches `Keyboard`, `KeyboardRaw`, and `Mouse` > from library `USBHID` as well as using the core `Serial` object for > ordinary USB serial I/O (`USBCDC`).
Commit 301d69d introduces a
PluggableUSBModule::getProductVersion()
method declaration, but it is not defined in the base class, resulting in a linker error when derived classes don't override it.I believe this method should be pure virtual:
Is there a guideline for which value third-party libraries should use? Should they just set the next available bit (16)? Is there an upper bound?
From the name of the function alone, it was not really clear to me how the function is intended to be used. The links in the commit message explain the rationale behind it, but it might be useful to have a comment or docstring in the PluggableUSBModule class documenting how and why to use it when defining a module.
The text was updated successfully, but these errors were encountered: