Skip to content

Commit

Permalink
Changes to the monoclr build so it builds for python 3.
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyroberts committed Nov 10, 2014
1 parent 6eb59ec commit 5062377
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 24 deletions.
11 changes: 11 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ def build_extension(self, ext):
if CONFIG == "Debug":
defines.extend(["DEBUG", "TRACE"])

if sys.platform != "win32" and DEVTOOLS == "Mono":
defines.append("MONO_LINUX")

if hasattr(sys, "abiflags"):
if "d" in sys.abiflags:
defines.append("PYTHON_WITH_PYDEBUG")
if "m" in sys.abiflags:
defines.append("PYTHON_WITH_PYMALLOC")
if "u" in sys.abiflags:
defines.append("PYTHON_WITH_WIDE_UNICODE")

cmd = [
_xbuild,
"pythonnet.sln",
Expand Down
57 changes: 43 additions & 14 deletions src/monoclr/clrmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,50 @@ PyDoc_STRVAR(clr_module_doc,
static PyNet_Args *pn_args;
char** environ = NULL;

#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef clrdef = {
PyModuleDef_HEAD_INIT,
"clr", /* m_name */
clr_module_doc, /* m_doc */
-1, /* m_size */
clr_methods, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
#endif

static PyObject *_initclr() {
PyObject *m;

/* Create the module and add the functions */
#if PY_MAJOR_VERSION >= 3
m = PyModule_Create(&clrdef);
#else
m = Py_InitModule3("clr", clr_methods, clr_module_doc);
#endif
if (m == NULL)
return;
PyModule_AddObject(m, "facade", Py_True);
Py_INCREF(Py_True);

pn_args = PyNet_Init(1);
if (pn_args->error) {
return NULL;
}
return m;
}

#if PY_MAJOR_VERSION >= 3
PyMODINIT_FUNC
PyInit_clr(void) {
return _initclr();
}
#else
PyMODINIT_FUNC
initclr(void)
{
PyObject *m;

/* Create the module and add the functions */
m = Py_InitModule3("clr", clr_methods, clr_module_doc);
if (m == NULL)
return;
PyModule_AddObject(m, "facade", Py_True);
Py_INCREF(Py_True);

pn_args = PyNet_Init(1);
if (pn_args->error) {
return;
}
_initclr();
}
#endif

22 changes: 22 additions & 0 deletions src/monoclr/python.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,29 @@

#include <Python.h>

#if (PY_MAJOR_VERSION > 2)
#include <wchar.h>
#endif

int main(int argc, char **argv) {
#if (PY_MAJOR_VERSION > 2)
int i, result;
size_t len;
wchar_t **wargv = (wchar_t**)malloc(sizeof(wchar_t*)*argc);
for (i=0; i<argc; ++ i) {
len = strlen(argv[i]);
wargv[i] = (wchar_t*)malloc(sizeof(wchar_t)*(len+1));
if (len == mbsrtowcs(wargv[i], (const char**)&argv[i], len, NULL))
wargv[i][len] = 0;
}
result = Py_Main(argc, wargv);
for (i=0; i<argc; ++i) {
free((void*)wargv[i]);
}
free((void*)wargv);
return result;
#else
return Py_Main(argc, argv);
#endif
}

104 changes: 94 additions & 10 deletions src/runtime/runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,50 @@ namespace Python.Runtime {

static class NativeMethods
{
#if MONO_LINUX
static public IntPtr LoadLibrary(string fileName) {
return dlopen(fileName, RTLD_NOW | RTLD_SHARED);
}

static public void FreeLibrary(IntPtr handle) {
dlclose(handle);
}

static public IntPtr GetProcAddress(IntPtr dllHandle, string name) {
// clear previous errors if any
dlerror();
var res = dlsym(dllHandle, name);
var errPtr = dlerror();
if (errPtr != IntPtr.Zero) {
throw new Exception("dlsym: " + Marshal.PtrToStringAnsi(errPtr));
}
return res;
}

const int RTLD_NOW = 2;
const int RTLD_SHARED = 20;

[DllImport("libdl.so")]
private static extern IntPtr dlopen(String fileName, int flags);

[DllImport("libdl.so")]
private static extern IntPtr dlsym(IntPtr handle, String symbol);

[DllImport("libdl.so")]
private static extern int dlclose(IntPtr handle);

[DllImport("libdl.so")]
private static extern IntPtr dlerror();
#else
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);

[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);


[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
#endif
}

public class Runtime {
Expand All @@ -54,49 +89,96 @@ public class Runtime {
#endif

#if (PYTHON23)
public const string dll = "python23";
public const string pyversion = "2.3";
public const int pyversionnumber = 23;
#endif
#if (PYTHON24)
public const string dll = "python24";
public const string pyversion = "2.4";
public const int pyversionnumber = 24;
#endif
#if (PYTHON25)
public const string dll = "python25";
public const string pyversion = "2.5";
public const int pyversionnumber = 25;
#endif
#if (PYTHON26)
public const string dll = "python26";
public const string pyversion = "2.6";
public const int pyversionnumber = 26;
#endif
#if (PYTHON27)
public const string dll = "python27";
public const string pyversion = "2.7";
public const int pyversionnumber = 27;
#endif
#if (PYTHON32)
public const string dll = "python32";
public const string pyversion = "3.2";
public const int pyversionnumber = 32;
#endif
#if (PYTHON33)
public const string dll = "python33";
public const string pyversion = "3.3";
public const int pyversionnumber = 33;
#endif
#if (PYTHON34)
public const string dll = "python34";
public const string pyversion = "3.4";
public const int pyversionnumber = 34;
#endif
#if ! (PYTHON23 || PYTHON24 || PYTHON25 || PYTHON26 || PYTHON27 || PYTHON32 || PYTHON33 || PYTHON34)
#error You must define one of PYTHON23 to PYTHON34
#endif

#if (PYTHON23)
internal const string dllBase = "python23";
#endif
#if (PYTHON24)
internal const string dllBase = "python24";
#endif
#if (PYTHON25)
internal const string dllBase = "python25";
#endif
#if (PYTHON26)
internal const string dllBase = "python26";
#endif
#if (PYTHON27)
internal const string dllBase = "python27";
#endif
#if (MONO_LINUX)
#if (PYTHON32)
internal const string dllBase = "python3.2";
#endif
#if (PYTHON33)
internal const string dllBase = "python3.3";
#endif
#if (PYTHON34)
internal const string dllBase = "python3.4";
#endif
#else
#if (PYTHON32)
internal const string dllBase = "python32";
#endif
#if (PYTHON33)
internal const string dllBase = "python33";
#endif
#if (PYTHON34)
internal const string dllBase = "python34";
#endif
#endif

#if (PYTHON_WITH_PYDEBUG)
internal const string dllWithPyDebug = "d";
#else
internal const string dllWithPyDebug = "";
#endif
#if (PYTHON_WITH_PYMALLOC)
internal const string dllWithPyMalloc = "m";
#else
internal const string dllWithPyMalloc = "";
#endif
#if (PYTHON_WITH_WIDE_UNICODE)
internal const string dllWithWideUnicode = "u";
#else
internal const string dllWithWideUnicode = "";
#endif

public const string dll = dllBase + dllWithPyDebug + dllWithPyMalloc + dllWithWideUnicode;

// set to true when python is finalizing
internal static Object IsFinalizingLock = new Object();
internal static bool IsFinalizing = false;
Expand All @@ -108,7 +190,7 @@ public class Runtime {
/// Intitialize the runtime...
/// </summary>
internal static void Initialize() {

is32bit = IntPtr.Size == 4;

if (0 == Runtime.Py_IsInitialized())
Expand Down Expand Up @@ -211,8 +293,10 @@ internal static void Initialize() {
#if (PYTHON32 || PYTHON33 || PYTHON34)
IntPtr dll = NativeMethods.LoadLibrary(Runtime.dll);
_PyObject_NextNotImplemented = NativeMethods.GetProcAddress(dll, "_PyObject_NextNotImplemented");
#if !MONO_LINUX
NativeMethods.FreeLibrary(dll);
#endif
#endif


// Determine whether we need to wrap exceptions for versions of
Expand Down

0 comments on commit 5062377

Please sign in to comment.