Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2020-12

callback from c with varargs

7 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Luca Olivetti

Hello,

I'm trying to use a c library where I can define a logging plugin.

The c prototype for the callback is

     void (*log)(void *logContext, UA_LogLevel level, UA_LogCategory
category, const char *msg, va_list args);

however I couldn't find a way to define a suitable callback in fpc since the "array of const" construct is not allowed with cdecl without external, i.e.

procedure LogLog(logContext: Pointer; level: UA_LogLevel; category:
UA_LogCategory; msg: PAnsiChar; const args:array of const);cdecl;

gives an error "Error: VarArgs directive (or '...' in MacPas) without CDecl/CPPDecl/MWPascal/StdCall and External".

I cannot add "external" (I don't want to call an external function, it's the library calling my function) or remove the cdecl (parameter passing wouldn't work then).

Is there some trick to define a function with varargs callable from the c library?

Bye

Luca
Jonas Maebe
to Luca Olivetti
Luca Olivetti wrote 11 lines
I'm trying to use a c library where I can define a logging plugin. The c prototype for the callback is     void (*log)(void *logContext, UA_LogLevel level, UA_LogCategory category, const char *msg, va_list args); however I couldn't find a way to define a suitable callback in fpc since the "array of const" construct is not allowed with cdecl without external, i.e.

It is indeed not possible to implement a function with C varargs in FPC.

Jonas

Luca Olivetti
to Jonas Maebe

El 19/12/20 a les 23:15, Jonas Maebe via fpc-pascal ha escrit:

Show quoted text 14 lines
On 19/12/2020 22:35, Luca Olivetti via fpc-pascal wrote: > I'm trying to use a c library where I can define a logging plugin. > > The c prototype for the callback is > >     void (*log)(void *logContext, UA_LogLevel level, UA_LogCategory > category, const char *msg, va_list args); > > > however I couldn't find a way to define a suitable callback in fpc since > the "array of const" construct is not allowed with cdecl without > external, i.e. It is indeed not possible to implement a function with C varargs in FPC.

I was afraid that's the answer :-(

as an ugly workaround, I wrote a c library that vsnprintf msg and args to a buffer and then calls a pascal function with no varargs.

It works but, as I said, it's ugly and I'd need to provide a .a for every platform I plan to use.

Is there a better/simpler way (apart from asking the library developers to use a callback with no varargs)?

Bye

Luca
Jonas Maebe
to Luca Olivetti
Luca Olivetti wrote 13 lines
El 19/12/20 a les 23:15, Jonas Maebe via fpc-pascal ha escrit: > It is indeed not possible to implement a function with C varargs in FPC. I was afraid that's the answer :-( as an ugly workaround, I wrote a c library that vsnprintf msg and args to a buffer and then calls a pascal function with no varargs. It works but, as I said, it's ugly and I'd need to provide a .a for every platform I plan to use. Is there a better/simpler way (apart from asking the library developers to use a callback with no varargs)?

No.

Jonas

Tomas Hajny
to Jonas Maebe
Jonas Maebe wrote 18 lines
On 20/12/2020 13:01, Luca Olivetti via fpc-pascal wrote: > El 19/12/20 a les 23:15, Jonas Maebe via fpc-pascal ha escrit: >> It is indeed not possible to implement a function with C varargs in >> FPC. > > I was afraid that's the answer :-( > > as an ugly workaround, I wrote a c library that vsnprintf msg and args > to a buffer and then calls a pascal function with no varargs. > > It works but, as I said, it's ugly and I'd need to provide a .a for > every platform I plan to use. > > Is there a better/simpler way (apart from asking the library > developers > to use a callback with no varargs)? No.

Not necessarily better than platform specific .a files mentioned by Luca, but the required playing with stack and registers should be still doable with a function written in assembler (inside the Pascal sources), shouldn't it?

Tomas

Jonas Maebe
to Tomas Hajny
Tomas Hajny wrote 23 lines
On 2020-12-20 14:00, Jonas Maebe via fpc-pascal wrote: > On 20/12/2020 13:01, Luca Olivetti via fpc-pascal wrote: >> El 19/12/20 a les 23:15, Jonas Maebe via fpc-pascal ha escrit: >>> It is indeed not possible to implement a function with C varargs in >>> FPC. >> >> I was afraid that's the answer :-( >> >> as an ugly workaround, I wrote a c library that vsnprintf msg and args >> to a buffer and then calls a pascal function with no varargs. >> >> It works but, as I said, it's ugly and I'd need to provide a .a for >> every platform I plan to use. >> >> Is there a better/simpler way (apart from asking the library developers >> to use a callback with no varargs)? > > No. Not necessarily better than platform specific .a files mentioned by Luca, but the required playing with stack and registers should be still doable with a function written in assembler (inside the Pascal sources), shouldn't it?

Yes, but you'd have to write it separately for each ABI.

Jonas

Luca Olivetti
to Jonas Maebe: No. Jonas

El 20/12/20 a les 14:00, Jonas Maebe via fpc-pascal ha escrit:

Show quoted text 16 lines
On 20/12/2020 13:01, Luca Olivetti via fpc-pascal wrote: > El 19/12/20 a les 23:15, Jonas Maebe via fpc-pascal ha escrit: >> It is indeed not possible to implement a function with C varargs in FPC. > > I was afraid that's the answer :-( > > as an ugly workaround, I wrote a c library that vsnprintf msg and args > to a buffer and then calls a pascal function with no varargs. > > It works but, as I said, it's ugly and I'd need to provide a .a for > every platform I plan to use. > > Is there a better/simpler way (apart from asking the library developers > to use a callback with no varargs)? No.

:-(

Oh, well, that's life.

Now I'm struggling to integrate my stub function under win32 (no problem with linux/64).

The linker complains about

Error: Undefined symbol: _vsnprintf
Error: Undefined symbol: _ua_pascallog

the first it's probably because it's missing some library (which?) but the second is defined in my program (and, as I said, it builds and works fine under linux/64) as:

procedure ua_pascallog(logContext: Pointer; level: UA_LogLevel;
   category: UA_LogCategory; msg: PAnsiChar);cdecl;export;

Any hint?

Bye

Luca