1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 <2021> 2022 2023 2024 2025 | Index | 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 <2021> 2022 2023 2024 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Extern "C" when defining aSub records |
From: | Simon Rose via Tech-talk <tech-talk at aps.anl.gov> |
To: | "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov> |
Date: | Tue, 2 Feb 2021 13:04:45 +0000 |
Hello - I am trying to understand how to register a cpp function for an EPICS aSub record (or something similar). In particular, I am trying to understand where and how to use the extern “C” directive. From what I understand, the extern “C” directive is there to tell the c++ compiler to use C-style linking and name mangling. This seems reasonable for any function that is going to be exposed
as a function that could be used outside of my specific library, e.g. by an aSub record. The function that is actually calling the aSub function is do_sub from aSubRecord.c. For reference: static long do_sub(aSubRecord *prec) { GENFUNCPTR pfunc = prec->sadr; long status; if (prec->snam[0] == 0) return 0; if (pfunc == NULL) { recGblSetSevr(prec, BAD_SUB_ALARM, INVALID_ALARM); return S_db_BadSub; } status = pfunc(prec); if (status < 0) recGblSetSevr(prec, SOFT_ALARM, prec->brsv); else prec->udf = FALSE; return status; } And the function is called in the line status = pfunc(prec); Given that this is from a .c file and not a .cpp file, does pfunc need to be defined with extern “C” linkage? The closest analog that I can find is from asyn, specifically asynPortDriver.cpp,
which defines a number of functions such as extern "C" {static asynStatus disconnect(void *drvPvt, asynUser *pasynUser) { … }} And these functions are later added into interfaces that, as I understand, are called from other parts of the code, hence their C-style linkages. Unfortunately, the example from the documentation seems to be implicitly in C, so that doesn’t help. In summary, my question is roughly as follows: 1. For a function defined in a .cpp file which is to be used as either the INAM or SNAM parameter in an aSub record, does that function need to be declared extern “C”? 2. What about the epicsExportFunction() line? What is the relationship between these two, and do either/both/none of them need to be extern “C”d? Thanks for your help, Cheers, -- Simon Rose Software Engineer European Spallation Source |