我有3个.c源文件: common.c、interface_1.c、interface_2.c。
在common.c中,我定义了一些函数和全局变量,在interface_1.c和interface_2.c中,将调用这些函数和全局变量。
现在,interface_1.c和interface_2.c将被编译成.dll,以供其他程序使用。问题是,虽然调用了两个dll文件,但common.c中定义的全局变量应该是相同的,这意味着:如果在调用interface_1.dll过程中更改了全局变量,则应该同时更改interface_2.dll中的相同变量。
背景我想用PLECS做电力电子仿真。有一个叫做DLL的块,它非常强大。用户可以编写c/cpp代码,并将它们编译成动态链接库。每个DLL块只能调用一个.dll文件。我有两个DLL块,并希望创建一个全局变量来在它们之间进行通信。下面显示了编译成dll的c源文件的模板。
DllHeader.h
#ifndef PLECSDLLHEADER_H_
#define PLECSDLLHEADER_H_
#if defined _WIN32
#define DLLEXPORT __declspec(dllexport)
#elif __GNUC__ >=4
#define DLLEXPORT __attribute__ ((visibility("default")))
#else
#define DLLEXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
#pragma pack(push, 4)
struct SimulationSizes {
int numInputs; /* the number of inputs that the DLL needs */
int numOutputs; /* the number of outputs that the DLL provides */
int numStates; /* the number of discrete states that the DLL needs */
int numParameters; /* the number of user parameters that the DLL needs */
};
struct SimulationState {
const double* const inputs; /* array of input values (read-only) */
double* const outputs; /* array of output values (to fill by DLL) */
double* const states; /* array of discrete states (read/write) */
const double* const parameters; /* array of parameters (read-only) */
const double time; /* current simulation time (read-only) */
const char* errorMessage; /* error message to set by DLL */
void* userData; /* pointer to any DLL data (untouched by PLECS) */
};
#pragma pack(pop)
/* Required: DLL needs to set all fields in aSizes. */
/* Called once before the simulation. */
DLLEXPORT void plecsSetSizes(struct SimulationSizes* aSizes);
/* Optional: DLL may acquire resources, initialize states and outputs. */
/* Called once during the initialization of a new simulation. */
DLLEXPORT void plecsStart(struct SimulationState* aState);
/* Required: DLL needs to set outputs depending on inputs and states. */
/* Called whenever the simulation time reaches a multiple of the sample */
/* time. */
DLLEXPORT void plecsOutput(struct SimulationState* aState);
/* Optional: DLL may release any acquired resources. */
/* Called when the simulation is finished, even when an error occured. */
DLLEXPORT void plecsTerminate(struct SimulationState* aState);
#ifdef __cplusplus
}
#endif
#endif /* PLECSDLLHEADER_H_ */
interface.c
#include "DllHeader.h"
//Map input and output parameters to meaningful names
#define in aState->inputs[0]
#define out aState->outputs[0]
DLLEXPORT void plecsSetSizes(struct SimulationSizes* aSizes)
{
aSizes->numInputs = 1;
aSizes->numOutputs = 1;
aSizes->numStates = 0;
aSizes->numParameters = 0; //number of user parameters passed in
}
//This function is automatically called at the beginning of the simulation
DLLEXPORT void plecsStart(struct SimulationState* aState)
{
// do some initialization ...
}
//This function is automatically called every sample time
//output is written to DLL output port after the output delay
DLLEXPORT void plecsOutput(struct SimulationState* aState)
{
// do some calculation ...
}
发布于 2020-09-17 12:36:31
使用LoadLibrary
是可行的。请注意在interface.c中应该指定common.dll的完整路径!最后给出了解决方案。
对于Lundin来说,它涉及到嵌入式开发,一些变量是基于时间的,这意味着它们始终存在,并由其他控制函数调用。例如,一个信号被采样并传递给一个变量,这个采样数据将被用于几个地方,例如滤波器,闭环控制.所以很难把这些凌乱的用法.
common.h
#ifndef COMMON_H_
#define COMMON_H_
#if defined _WIN32
#define DLLEXPORT __declspec(dllexport)
#elif __GNUC__ >=4
#define DLLEXPORT __attribute__ ((visibility("default")))
#else
#define DLLEXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
#pragma pack(push, 4)
typedef struct{
float a;
float b;
} Coord;
#pragma pack(pop)
extern Coord curPos;
DLLEXPORT Coord GetcurPos(void);
DLLEXPORT float getMax(float a, float b);
DLLEXPORT void SetcurPos(float a, float b);
#ifdef __cplusplus
}
#endif
#endif /* COMMON_H_ */
common.c
#include "common.h"
Coord curPos;
DLLEXPORT float getMax(float a, float b){
return a>b?a:b;
}
DLLEXPORT Coord GetcurPos(void){
return curPos;
}
DLLEXPORT void SetcurPos(float a, float b){
curPos.a=a;
curPos.b=b;
}
interface_a.c
#include "DllHeader.h"
#include <windows.h>
#include "common.h"
//Map input and output parameters to meaningful names
#define in aState->inputs[0]
#define out aState->outputs[0]
HMODULE module;
typedef float(*AddFunc)(float, float);
typedef Coord (*PosGetter)(void);
AddFunc dllmax;
PosGetter getCurPos;
DLLEXPORT void plecsSetSizes(struct SimulationSizes* aSizes)
{
aSizes->numInputs = 1;
aSizes->numOutputs = 1;
aSizes->numStates = 0;
aSizes->numParameters = 0; //number of user parameters passed in
}
DLLEXPORT void plecsStart(struct SimulationState* aState)
{
module = LoadLibrary(TEXT("D:\\Simulation\\PLECSLearn\\DLL\\global_test\\common.dll"));
if (module == NULL)
{
aState->errorMessage = "Failed to load common.dll";
}
dllmax = (AddFunc)GetProcAddress(module, "getMax");
getCurPos = (PosGetter)GetProcAddress(module, "GetcurPos");
}
//This function is automatically called every sample time
//output is written to DLL output port after the output delay
DLLEXPORT void plecsOutput(struct SimulationState* aState)
{
if (getCurPos().a == 1){
out = 2;
} else {
out = -1;
}
// out = dllmax(200,300);
}
interface_b.c
#include "DllHeader.h"
#include <windows.h>
#include "common.h"
//Map input and output parameters to meaningful names
#define in aState->inputs[0]
#define out aState->outputs[0]
HMODULE module;
typedef float(*AddFunc)(float, float);
typedef Coord (*PosGetter)(void);
typedef void (*PosSetter)(float, float);
AddFunc dllmax;
PosGetter getCurPos;
PosSetter setCurPos;
DLLEXPORT void plecsSetSizes(struct SimulationSizes* aSizes)
{
aSizes->numInputs = 1;
aSizes->numOutputs = 1;
aSizes->numStates = 0;
aSizes->numParameters = 0; //number of user parameters passed in
}
DLLEXPORT void plecsStart(struct SimulationState* aState)
{
module = LoadLibrary(TEXT("D:\\Simulation\\PLECSLearn\\DLL\\global_test\\common.dll"));
if (module == NULL)
{
aState->errorMessage = "Failed to load common.dll";
}
dllmax = (AddFunc)GetProcAddress(module, "getMax");
getCurPos = (PosGetter)GetProcAddress(module, "GetcurPos");
setCurPos = (PosSetter)GetProcAddress(module, "SetcurPos");
}
//This function is automatically called every sample time
//output is written to DLL output port after the output delay
DLLEXPORT void plecsOutput(struct SimulationState* aState)
{
static int cnt = 0;
if (cnt<5000){
setCurPos(0,0);
}else{
setCurPos(1,2);
}
cnt++;
out = getCurPos().a;
}
https://stackoverflow.com/questions/63933786
复制相似问题