1

I have the following code:

// note: this implicity defines onoff_pub_0 as a static
ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_0, 2 + 3, ROLE_NODE);
static esp_ble_mesh_gen_onoff_srv_t onoff_server_0 = {
    .rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
    .rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
};

// ...

static esp_ble_mesh_model_t root_models[] = {
    ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_0, &onoff_server_0),\
    // ...
};

I'd like to be able to isolate these definition into separate file, and root_models in a separate file (to allow for reusability of code), but I can't seem to get around accessing static variables from another file (and yes, I've read a lot of posts on StackOverflow about using statics in C for encapsulation)... Is there any better option when the library I'm using implements static variables in their macros?

FYI, here's a more complete example if someone wants to propose a more general architecture approach...

joshp
  • 706
  • 5
  • 22
  • 4
    If you want to share global variables across multiple files, don't declare them static. All static is doing is forcing the names to be local to the defining file, which you don't want. – Tom Karzes Aug 05 '23 at 06:20
  • 1
    See [What does "static" mean in C?](/q/572547/4850040) – Toby Speight Aug 05 '23 at 08:12
  • @TomKarzes I’m not defining them that way, the library I’m interacting with does that, so I don’t have control over it – joshp Aug 06 '23 at 00:00
  • @joshp The only other thing you can do is have your other files export a function that you call, passing it the addresses of your static variables. They can then save those addresses and use them to access the statics. – Tom Karzes Aug 06 '23 at 00:14
  • @TomKarzes I think I’ve been trying to do that without success lol. Do you mind posting an example and I’ll accept the answer? – joshp Aug 06 '23 at 02:20
  • @joshp The problem is I don't understand the exact restrictions you're under, so I don't know if this would work, but at a minimum you'd need to have at least one source file that can access those static variables. If you have that, then you just need to add a function to that file that makes those pointers available. Or, you could even declare some non-static global variables, and initialize them to point to the static variables. But again, it all depends on what you're able to do. – Tom Karzes Aug 06 '23 at 02:41
  • @joshp One way or another, it requires being able to add code to the file that defines the static variables. If you can do that, then you can make them available. If you can't do that, then you're pretty much stuck. – Tom Karzes Aug 06 '23 at 02:42

2 Answers2

3

If onoff_pub_0 is unavoidably static (due to to the library you're using), and you want to access that variable in a different file to where it's defined, then you can create a function to return a pointer to onoff_pub_0 (as long as you know what C type onoff_pub_0 is).

So in file1.c you have (where I'm using onoff_pub_t for the type):

ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_0, 2 + 3, ROLE_NODE);
static esp_ble_mesh_gen_onoff_srv_t onoff_server_0 = {
    .rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
    .rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
};

static esp_ble_mesh_model_t root_models[] = {
    ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_0, &onoff_server_0),\
    // ...
};

// Function to return a pointer to onoff_pub_0
onoff_pub_t GetOnOff0PubPtr(void)
{
  return &onoff_pub_0;
}

Then in file1.h you have:

#include "some header file .h" // include whatever is necessary for onoff_pub_t
onoff_pub_t GetOnOff0PubPtr(void);

And now in file2.c:

#include "file1.h"

  onoff_pub_t *on_off_pub_0_ptr = GetOnOff0PubPtr(); // get a pointer to static on_off_pub_0 in file2.c
  if (*on_off_pub_0_ptr == ...) // do something with the value of on_off_pub_0 by dereferencing on_off_pub_0_ptr
brhans
  • 402
  • 3
  • 10
  • Note that calls to `GetOnOff0PubPtr();` must be within a function in C - you can't have something like `onoff_pub_t *on_off_pub_0_ptr = GetOnOff0PubPtr();` at file scope. – Andrew Henle Aug 06 '23 at 13:24
1

The whole purpose of static at file scope is to restrict visibility of those declarations to that single translation unit.

If you want to use definitions from other TUs, they need to be extern, which is the default at this level if you don't specify static.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
  • As comment above, I don’t have control over that, it’s the way the library I’m working with does it… – joshp Aug 06 '23 at 00:01