On 2/2/21 5:04 AM, Simon Rose via Tech-talk wrote:
> 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.
While in theory I think that extern "C" could effect calling convention, in
practice it does not. So the only place extern "C" is needed is around
the epicsExport*() macros.
The actual global symbol name is determined by the epicsExport*,
which is working from a pointer to your function, so c++ name mangling
isn't relevant.
> 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
>
- Replies:
- Re: Extern "C" when defining aSub records Till Straumann via Tech-talk
- References:
- Extern "C" when defining aSub records Simon Rose via Tech-talk
- Navigate by Date:
- Prev:
Extern "C" when defining aSub records Simon Rose via Tech-talk
- Next:
Questions about Pilatus detectors / latency Ralph Lange via Tech-talk
- 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
- Navigate by Thread:
- Prev:
Extern "C" when defining aSub records Simon Rose via Tech-talk
- Next:
Re: Extern "C" when defining aSub records Till Straumann via Tech-talk
- 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
|