How to handle calling convention when wrapping C-code in Cython?

385 views Asked by At

I'm trying to interface PDFium with Cython and ran into these defines/signatures:

#if defined(COMPONENT_BUILD)

#if defined(WIN32)
#if defined(FPDF_IMPLEMENTATION)
#define FPDF_EXPORT __declspec(dllexport)
#else
#define FPDF_EXPORT __declspec(dllimport)
#endif  // defined(FPDF_IMPLEMENTATION)
#else
#if defined(FPDF_IMPLEMENTATION)
#define FPDF_EXPORT __attribute__((visibility("default")))
#else
#define FPDF_EXPORT
#endif  // defined(FPDF_IMPLEMENTATION)
#endif  // defined(WIN32)
#else
#define FPDF_EXPORT
#endif  // defined(COMPONENT_BUILD)

#if defined(WIN32) && defined(FPDFSDK_EXPORTS)
#define FPDF_CALLCONV __stdcall
#else
#define FPDF_CALLCONV
#endif


FPDF_EXPORT void FPDF_CALLCONV
FPDF_InitLibraryWithConfig(const FPDF_LIBRARY_CONFIG* config);

I'm just used to the simple function declaration with

return_type function_name();

How to wrap signatures containing calling conventions in Cython?

2

There are 2 answers

7
Lev M. On BEST ANSWER

Unfortunately, I could not find the specific macros or the function you reference here: https://github.com/PDFium/PDFium

You should probably add what specific version of your library you are using.

However, there are things in C function declarations besides return type, function name, and parameters that come from outside C it self.

One specific one, which is not part of the C standard, is the calling convention, which specifies how sending parameters and returning from function works.

Since the keywords to specify this convention are compiler specific, it makes sense to put them in a conditional macro, to make the code portable.

It may also be done to support cross-compilation for different hardware.

So FPDF_CALLCONV is most likely something like this:

#ifdef SOME_CONDITION_TO_USE_STD_CALL
    #define FPDF_CALLCONV __stdcall
#endif

Another non standard option in C (and C++) programs is a directive to export a function when building a DLL on Windows.

Since this is platform specific, to make C code cross-platform, it also needs to be in a conditional macro.

So, FPDF_EXPORT is likely something like this:

#ifdef WINDOWS
    #define FPDF_EXPORT __declspec(dllexport)
#else
    #define FPDF_EXPORT
#endif

Note, that on other platforms this kind of "marking" does not exist, so the macro can expand to nothing, leaving the function declaration in a more familiar form.

It should also be left blank in the version of h file you include to use the library as opposed to the one used to compile the library, as you don't need this prefix to call the function.

To conclude, it is likely you can omit these two macros in your Cuthon interface, assuming the library you are using is compatible with your platform.

3
zpasztor On

FPDF_EXPORT and FPDF_CALLCONV are Macros, they are defined in the file : https://pdfium.googlesource.com/pdfium/+/master/public/fpdfview.h

They are needed here because the library is available for different systems, and different systems have different conventions for creating the library interface.

These calls are extensions to the format you are familiar with:

return_type function_name(args) 

For example you can see that FPDF_CALLCONV dissapears unless you are building the library for windows.