Skip to content
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

Only provide a C-language interface in libprojectM by default. #529

Closed
kblaschke opened this issue Aug 16, 2021 · 3 comments · Fixed by #530
Closed

Only provide a C-language interface in libprojectM by default. #529

kblaschke opened this issue Aug 16, 2021 · 3 comments · Fixed by #530

Comments

@kblaschke
Copy link
Member

Is your feature request related to a problem? Please describe.
Currently, projectM only supports a C++ interface in both static and shared libraries. This works fine as long as both projectM and applications integrating it are compiled with the same toolchain, C++ library and C++ language level, but will cause issues from dynamic linker error to segmenation faults if there are differences, as STL types are used in the interface.

In detail: STL types are, as the name suggests, template classes with (mostly) header-only implementations. Between different compilers, compiler versions and depending on the C++ language level selected during compilation, STL type implementations - specifically the memory layout - will differ. An std::string returned by a projectM function (for example the current preset name) would be free'd by the host application, but the destructor of this std::string might expect a different layout of members than the implementation used to compile projectM.

Describe the solution you'd like
Adding a C wrapper that exposes only C-style functions instead of the OOP interface, hiding the ProjectM class instance and only using standard types like char*, int, float etc. as parameters and return values.

The projectM class instance pointer will only be returned as an opaque pointer type, passed to each subsequent functions call. The wrapper functions then convert the pointer back to the proper C++ class instance to call the member functions in the specified instance.

Using the wrapper, all STL operations are done with the same implementation as the projectM code itself. For returned char* type values, a free function should be provided by the wrapper as some platforms like Windows separate heaps between applications and shared libraries, which can cause an application-side free on a library-allocated pointer to crash the program.

To make the C++ interface still useable, there are two options:

  1. Only install the C++ headers if a new build option like INSTALL_CXX_HEADERS is specified, with an author warning emitted that this can cause problems.
  2. Always install the C++ headers as usual, but add a #pragma warning (that can be suppressed) to the main C++ header that using this interface requires some additional care.

Describe alternatives you've considered
There is no real alternative, as there's no way to check STL compatibility on library load.

@revmischa
Copy link
Collaborator

I don't know enough to have a strong opinion here but I believe exposing a C-style interface sounds very reasonable and will hopefully make it easier to create bindings in other languages. A Rust or Python or TypeScript projectM library one day would be super cool.

@vikingsloth
Copy link

I agree, a C interface would provide easy access to other languages and maybe provide some long term stability. I honestly don't see many C++ library interfaces outside of things that are meant to extend the functionality of C++.

@kblaschke
Copy link
Member Author

Initial implementation of an API wrapper is committed.

IMO there is still a lot to be done on projectM's public interface:

  • The preset queueing functions are declared in projectM.hpp, but unimplemented.
  • The PCM class offers many functions to add audio data, with different data types - fixed sized arrays and 1/2 channel functions. This can probably be reduced to a single function per sample format, taking the data, number of channels and number of samples, also possibly allowing for multi-channel (5.1, 7.1) audio to be added without additional conversion.
  • The naming of playlist and rating related functions looks a bit random.

This might be something to clean up before the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

3 participants