fix epicsExport for volatile and const variables

This commit is contained in:
2025-03-12 11:59:49 +01:00
parent 93ba98cdca
commit acf4c92697
6 changed files with 50 additions and 21 deletions

View File

@ -22,7 +22,7 @@ __Add new items below here__
### epicsExport simplifications ### epicsExport simplifications
`epicsExportAddress()`, `epicsExportRegistrar()` and `epicsRegisterFunction()` `epicsExportAddress()`, `epicsExportRegistrar()` and `epicsRegisterFunction()`
no loger require to be wrapped in `extern "C" { }` in C++ code. no longer require to be wrapped in `extern "C" { }` in C++ code.
### Build system `$(PYTHON)` default changed ### Build system `$(PYTHON)` default changed

View File

@ -231,6 +231,7 @@ TARGETS += $(COMMON_DIR)/epicsExportTestIoc.dbd
DBDDEPENDS_FILES += epicsExportTestIoc.dbd$(DEP) DBDDEPENDS_FILES += epicsExportTestIoc.dbd$(DEP)
epicsExportTestIoc_DBD += base.dbd epicsExportTestIoc_DBD += base.dbd
epicsExportTestIoc_DBD += epicsExportTest.dbd epicsExportTestIoc_DBD += epicsExportTest.dbd
TESTFILES += $(COMMON_DIR)/epicsExportTestIoc.dbd ../epicsExportTest.db
TESTLIBRARY += epicsExportTestLib TESTLIBRARY += epicsExportTestLib
epicsExportTestLib_SRCS += epicsExportTest.c epicsExportTestLib_SRCS += epicsExportTest.c
epicsExportTestLib_LIBS += dbCore Com epicsExportTestLib_LIBS += dbCore Com

View File

@ -27,6 +27,8 @@
#include <epicsExport.h> #include <epicsExport.h>
int i1, i2; int i1, i2;
volatile int v1=10, v2=20;
const int c1=100, c2=200;
static long myReadLongin(struct dbCommon* prec) static long myReadLongin(struct dbCommon* prec)
{ {
@ -40,8 +42,8 @@ static long myReadLongin(struct dbCommon* prec)
return 0; return 0;
} }
/* Also test cast from user-specific mydset to dset */ /* Also test cast from user-specific const mydset to dset */
struct mydset { const struct mydset {
long number; long number;
long (*report)(int); long (*report)(int);
long (*init)(int); long (*init)(int);
@ -118,6 +120,8 @@ static long aSubProc2(aSubRecord* prec) {
/* Test without wrapping */ /* Test without wrapping */
epicsExportAddress(int, i1); epicsExportAddress(int, i1);
epicsExportAddress(int, v1);
epicsExportAddress(int, c1);
epicsExportAddress(dset, dset1); epicsExportAddress(dset, dset1);
epicsExportRegistrar(registrar1); epicsExportRegistrar(registrar1);
epicsExportRegistrar(registrar3); epicsExportRegistrar(registrar3);
@ -129,6 +133,8 @@ epicsRegisterFunction(aSubProc1);
extern "C" { extern "C" {
#endif #endif
epicsExportAddress(int, i2); epicsExportAddress(int, i2);
epicsExportAddress(int, v2);
epicsExportAddress(int, c2);
epicsExportAddress(dset, dset2); epicsExportAddress(dset, dset2);
epicsExportRegistrar(registrar2); epicsExportRegistrar(registrar2);
epicsExportRegistrar(registrar4); epicsExportRegistrar(registrar4);

View File

@ -1,5 +1,9 @@
variable(i1,int) variable(i1,int)
variable(i2,int) variable(i2,int)
variable(v1,int)
variable(v2,int)
variable(c1,int)
variable(c2,int)
device(longin, CONSTANT, dset1, "dset1") device(longin, CONSTANT, dset1, "dset1")
device(longin, CONSTANT, dset2, "dset2") device(longin, CONSTANT, dset2, "dset2")
registrar(registrar1) registrar(registrar1)

View File

@ -18,11 +18,30 @@
void epicsExportTestIoc_registerRecordDeviceDriver(struct dbBase *); void epicsExportTestIoc_registerRecordDeviceDriver(struct dbBase *);
static int* testVarEquals(const char* name, int expected)
{
const iocshVarDef *var;
int *p;
var = iocshFindVariable(name);
if (!var) {
testFail("Cannot access variable %s", name);
return NULL;
}
if (var->type != iocshArgInt) {
testFail("Variable %s has wrong type", name);
return NULL;
}
p = (int*)(var->pval);
testOk(*p == expected, "Variable %s == %d", name, expected);
return p;
}
MAIN(epicsExportTest) MAIN(epicsExportTest)
{ {
const iocshVarDef *var_i1, *var_i2; int *p1, *p2;
testPlan(26); testPlan(30);
testdbPrepare(); testdbPrepare();
testdbReadDatabase("epicsExportTestIoc.dbd", 0, 0); testdbReadDatabase("epicsExportTestIoc.dbd", 0, 0);
epicsExportTestIoc_registerRecordDeviceDriver(pdbbase); epicsExportTestIoc_registerRecordDeviceDriver(pdbbase);
@ -52,22 +71,21 @@ MAIN(epicsExportTest)
testdbGetFieldEqual("asub2.B", DBF_LONG, 4); testdbGetFieldEqual("asub2.B", DBF_LONG, 4);
testDiag("Testing if variable access works"); testDiag("Testing if variable access works");
var_i1 = iocshFindVariable("i1"); p1 = testVarEquals("i1", 2);
var_i2 = iocshFindVariable("i2"); p2 = testVarEquals("i2", 2);
if (var_i1 && var_i2 && var_i1->type == iocshArgInt && var_i2->type == iocshArgInt) { testVarEquals("v1", 10);
int *pi1 = (int*)(var_i1->pval); testVarEquals("v2", 20);
int *pi2 = (int*)(var_i2->pval); testVarEquals("c1", 100);
testVarEquals("c2", 200);
testOk(*pi1==2, "Variable i1 counted registrars: %d == 2", *pi1); if (p1 && p2) {
testOk(*pi2==2, "Variable i2 counted registrars: %d == 2", *pi2);
testDiag("Testing if variables are accessible from iocsh"); testDiag("Testing if variables are accessible from iocsh");
testOk(iocshCmd("var i1,4") == 0, "Setting i1 = 4 in iocsh"); testOk(iocshCmd("var i1,4") == 0, "Setting i1 = 4 in iocsh");
testOk(iocshCmd("var i2,5") == 0, "Setting i2 = 5 in iocsh"); testOk(iocshCmd("var i2,5") == 0, "Setting i2 = 5 in iocsh");
testOk(*pi1==4, "Variable i1: %d == 4", *pi1); testOk(*p1==4, "Variable i1 == 4");
testOk(*pi2==5, "Variable i2: %d == 5", *pi2); testOk(*p2==5, "Variable i2 == 5");
} else {
testFail("Cannot access variables i1, i2");
} }
testIocShutdownOk(); testIocShutdownOk();
testdbCleanup(); testdbCleanup();
return testDone(); return testDone();

View File

@ -41,6 +41,10 @@ extern "C" {
typedef void (*REGISTRAR)(void); typedef void (*REGISTRAR)(void);
#ifdef __cplusplus
}
#endif
#define EPICS_EXPORT_POBJ(typ, obj) pvar_ ## typ ## _ ## obj #define EPICS_EXPORT_POBJ(typ, obj) pvar_ ## typ ## _ ## obj
#define EPICS_EXPORT_PFUNC(fun) EPICS_EXPORT_POBJ(func, fun) #define EPICS_EXPORT_PFUNC(fun) EPICS_EXPORT_POBJ(func, fun)
@ -79,7 +83,7 @@ typedef void (*REGISTRAR)(void);
#ifdef __cplusplus #ifdef __cplusplus
#define epicsExportAddress(typ, obj) \ #define epicsExportAddress(typ, obj) \
extern "C" { epicsShareExtern typ *EPICS_EXPORT_POBJ(typ,obj); } \ extern "C" { epicsShareExtern typ *EPICS_EXPORT_POBJ(typ,obj); } \
epicsShareDef typ *EPICS_EXPORT_POBJ(typ, obj) = reinterpret_cast<typ *>(&obj) epicsShareDef typ *EPICS_EXPORT_POBJ(typ, obj) = (typ *) (char *) &obj
#else #else
#define epicsExportAddress(typ, obj) \ #define epicsExportAddress(typ, obj) \
epicsShareExtern typ *EPICS_EXPORT_POBJ(typ,obj); \ epicsShareExtern typ *EPICS_EXPORT_POBJ(typ,obj); \
@ -136,8 +140,4 @@ typedef void (*REGISTRAR)(void);
epicsExportRegistrar(register_func_ ## fun) epicsExportRegistrar(register_func_ ## fun)
#endif #endif
#ifdef __cplusplus
}
#endif
#endif /* INC_epicsExport_H */ #endif /* INC_epicsExport_H */