Search code examples
pythonfunctionc++11headerswig

Strange C++ header file function declaration


I'm reading some source code that I'm trying to compile into python bindings, when I try swig -c++ -python my_interface.i I get a strange error.

I know the source code is written in C++11.

// module.hpp
#pragma once

namespace module
{
    MODULE_API void getVersion (unsigned &params);
}
// my_interface.i
%module my_api
%{
#include "module.hpp"
%}

%include "module.hpp"

I don't have access to the source files, just the headers, and a shared library that we can call modulelib.so.

Does anybody know what the MODULE_API before the function return type means?

When I try to compile right now I get the error module.hpp:29: Error: Syntax error in input(1) When I remove the MODULE_API the output moves to the next function declaration, because they all have this style of declaration, I'd delete them all, but I feel like that's going to break something.

Right now when I run swig -v -wall -c++ -python my_interface.i I recieve an error:

Language subdirectory: python
Search paths:
   ./
   ./swig_lib/python/
   /usr/share/swig3.0/python/
   ./swig_lib/
   /usr/share/swig3.0/
Preprocessing...
Starting language-specific parse...
module.hpp:6: Error: Syntax error in input(1).

Solution

  • This is a common pattern to handle symbol visibility. Windows, for example, requires you to define functions with __declspec(dllexport) when compiling a library (so the linker knows to make the corresponding symbols externally visible), and __declspec(dllimport) when using/linking a library (so the linker knows that those symbols are to be imported from a DLL).

    To avoid having to have two different headers (one for compiling, one for using the library), conditional defines are used:

    #ifdef WIN32
    
      #ifdef MODULE_EXPORTS
        #define MODULE_API __declspec(dllexport)
      #else
        #define MODULE_API __declspec(dllimport)
      #endif
    
    #else
      #define MODULE_API
    #endif
    

    This is merely an example. It does not have to be MODULE_API at all. Some projects use GCC's __attribute__((visibility("default"))) and __attribute__((visibility("hidden"))), but Windows is where this scheme originated, as Windows' default is to hide symbols.