py_version.hpp
 1  
 2  #ifndef __PY_VERSION_HPP__
 3  #define __PY_VERSION_HPP__
 4  
 5  
 6  #include <cstring>
 7  
 8  enum PythonVersion {
 9      PythonVersion_Unknown,
10      PythonVersion_25 = 0x0205,
11      PythonVersion_26 = 0x0206,
12      PythonVersion_27 = 0x0207,
13      PythonVersion_30 = 0x0300,
14      PythonVersion_31 = 0x0301,
15      PythonVersion_32 = 0x0302,
16      PythonVersion_33 = 0x0303,
17      PythonVersion_34 = 0x0304,
18      PythonVersion_35 = 0x0305,
19      PythonVersion_36 = 0x0306,
20      PythonVersion_37 = 0x0307,
21      PythonVersion_38 = 0x0308,
22      PythonVersion_39 = 0x0309,
23      PythonVersion_310 = 0x030A,
24      PythonVersion_311 = 0x030B
25  };
26  
27  
28  #ifdef _WIN32
29  
30  typedef const char* (GetVersionFunc)();
31  
32  static PythonVersion GetPythonVersion(HMODULE hMod) {
33      auto versionFunc = reinterpret_cast<GetVersionFunc*>(GetProcAddress(hMod, "Py_GetVersion"));
34      if (versionFunc == nullptr) {
35          return PythonVersion_Unknown;
36      }
37      const char* version = versionFunc();
38  
39  
40  #else // LINUX -----------------------------------------------------------------
41  
42  typedef const char* (*GetVersionFunc) ();
43  
44  static PythonVersion GetPythonVersion(void *module) {
45      GetVersionFunc versionFunc;
46      *(void**)(&versionFunc) = dlsym(module, "Py_GetVersion");
47      if(versionFunc == nullptr) {
48          return PythonVersion_Unknown;
49      }
50      const char* version = versionFunc();
51  
52  #endif //_WIN32
53  
54      if (version != nullptr && strlen(version) >= 3 && version[1] == '.') {
55          if (version[0] == '2') {
56              switch (version[2]) {
57              case '5': return PythonVersion_25;
58              case '6': return PythonVersion_26;
59              case '7': return PythonVersion_27;
60              }
61          }
62          else if (version[0] == '3') {
63              switch (version[2]) {
64              case '0': return PythonVersion_30;
65              case '1':
66                  if(strlen(version) >= 4){
67                      if(version[3] == '0'){
68                          return PythonVersion_310;
69                      }
70                      if(version[3] == '1'){
71                          return PythonVersion_311;
72                      }
73                  }
74                  return PythonVersion_Unknown; // we don't care about 3.1 anymore...
75              
76              case '2': return PythonVersion_32;
77              case '3': return PythonVersion_33;
78              case '4': return PythonVersion_34;
79              case '5': return PythonVersion_35;
80              case '6': return PythonVersion_36;
81              case '7': return PythonVersion_37;
82              case '8': return PythonVersion_38;
83              case '9': return PythonVersion_39;
84              }
85          }
86      }
87      return PythonVersion_Unknown;
88  }
89  
90  #endif