As we all work through using C Blocks, I’ve seen mention of using static variables. I’m thinking that this is a bad idea generally. Here’s why (sorry for the lengthy explanation):
The C Block code is a component implemented in a DLL. We must assume that more than one instance of the component might be present in a higher-level schematic. However, there will be only one copy of the DLL running regardless of how many instances are present in the schematic. Static variables in the DLL are shared across all component instances. To work around this, Mike provides a “per-instance” structure pointer for each instance to allocate unique memory.
For those not familiar with DLLs, well, there must be a lot of “magic” under the QSpice hood. When a simulation is run, it must:
- Load the DLL. This can fail if the DLL isn’t found.
- If found, call DllMain() to let the DLL initialize itself. The DLL can return 0 if it cannot successfully initialize. (Example, the DLL might attempt to load other DLLs which cannot be found or fail to initialize properly for any other reason that it likes.)
- Load handles for the various DLL methods/functions that QSpice knows about. The minimum would be the template-generated extern “C” __declspec(dllexport) void mod_name_lowercase(
struct smod_name_original_case **opaque, double t, union uData *data) function. Others include the optional MaxExtStepSize() and Trunc() functions. Any and all of these might not exist in the component code and QSpice would call them only if it successfully loads the handles. - When the QSpice simulation ends, it calls Destroy() for each instance passing in the allocated memory per-instance memory handle. (Failure to free memory here will presumably cause memory leaks. The component code must also release any other resources allocated by the component.)
The point is, this DLL stuff is a bit more complicated than a casual programmer might realize.
[Now, I’ll suggest that some of this would be less confusing if the template-generator did NOT name the per-instance data structure with a module-derived name. It would make more sense to simply call it sPerInstanceData or similar.]
Anyway, if your component code needs to support multiple schematic instances with independent states, use the “per-instance” structure. Avoid static DLL variables.
As always, I could be wrong. Corrections welcome.