Reputation: 144
I’m developing my first embedded application (on an Arduino) which takes inputs from and controls a number of off the shelf components. It is a completely private non-commercial project. (Just a bit of fun / training exercise for my own benefit.)
An Arduino library is just a zipped collection of C++ source with a single C++ and .h file that present the interface to the library. For the purpose of this question just consider each library as a collection of source that I acquired from someone else.
Two of the more complex components can be controlled using freely available libraries (with good reputations) which I wish to use to avoid re-inventing the wheel. However, both libraries declare a number of arrays which consume too much of the very limited data space available.
On start up my application will test a switch which will determine which of the two components will be used until the next power cycle. I will never use both components at the same time.
I would like to change the libraries to share the same space in RAM but I’ve found my knowledge of C++ too limited.
Library A declares a buffers as follows:
class A
{
public:
char name[50];
char address[100];
}
Library B declares a buffers as follows:
class B
{
public:
static char name[];
static char address[];
}
and the caller of B is required to define the buffers as follows:
char B::name[50];
char B::address[100];
I can easily make a small number changes to library A to pass in a pointer to buffers which are defined by my application. However, library B is trickier because the buffers are declared as static and used by a number of static methods.
I could change library B to convert all the static methods that use these buffers to non-static methods. But this would be significant work and deviate from the original more that I would like. Such changes would make it harder for me to update my application to use a later version of library from the original author if I want to one day.
I assume that I could pass the address of B:name[] and B::address[] to library A but passing a buffer of class B to class A feels like a crude bodge.
Given the hardware context, I wouldn't mind defining a single big buffer big enough for name and address and then using offsets with the buffer within the libraries. But my primary problem prevents me doing that in library B.
In summary my problem is I can't get the two libraries to share a buffer that is completely defined outside of both classes without changing library B so that it doesn't use static methods.
Can anyone suggest any language tricks for solving my problem neatly with either a modest number of code changes or changes that could be made automatically or using macros?
Upvotes: 4
Views: 571
Reputation: 180155
The core problem is that sizeof(A)>=150
but both sizeof(B::name) < 150
and sizeof(B::address) <150
. That is to say, neither of the two arrays used by B are big enough to hold a single A object. Hence, you'll need a single contiguous 150+ byte allocation for A, as it stands.
As noted, there's no real need for that. There's no real reason A
needs contiguous storage; it can use char* name
and char* address
. They can point to the two buffers for B
. Yes, that's a kludge. Yes, kludges are what you use on underpowered systems such as the Arduino. On real systems, you'd simply call dlopen()
on either libA
or libB
, but not both. Un-loaded libraries don't use memory.
Upvotes: 0
Reputation: 6834
Not quite sure the level of change that you feel ok with.
But how about just changing the header and application for class B
, leaving the rest of its implementation intact ?
class B
{
public:
static char* name;
static char* address;
}
The caller of B defines the buffers as follows:
char name[50];
char address[100];
char* B::name = name;
char* B::address = address;
You can then also pass name
and address
to class A
as you planned.
So the question is: Why should this work for the other code in B?
Firstly, it will need to be compiled with the same header. Other than that, given that it could not actually directly see the sizes of the arrays, it will more or less work correctly without further changes.
Where there might be an issue is if it contains methods or functions that expected an array parameter but not a pointer. Arrays decay to pointers but not the other way around. If this is the case, you'd also have to change the parameters to those functions.
However, given that there is a singleton pattern and static member in the first place, I'm betting this issue is not present to start with.
Upvotes: 1