You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
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.
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.
The text was updated successfully, but these errors were encountered:
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.
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++.
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.
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 thisstd::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, afree
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:
INSTALL_CXX_HEADERS
is specified, with an author warning emitted that this can cause problems.#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.
The text was updated successfully, but these errors were encountered: