Skip to content

Incorrect marshalling of string in Py_SetPythonHome #179

@leomeuk

Description

@leomeuk

I noticed that when PythonEngine.PythonHome was set and a subsequent Initialize() call was made my .Net application would close unexpectedly.

It looks like the call to Py_SetPythonHome made in runtime.cs is implicitly marshalling the string to a char array for the unmanaged code. My suspicion is that the Python sourcecode is keeping a record of the pointer rather than making a copy of the data. The managed runtime will free the memory allocated to char array as soon as the function finishes executing leaving a dangling pointer. This then leads to the unexpected Initialize() behaviour.

[DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl,
    ExactSpelling = true, CharSet = CharSet.Ansi)]
internal unsafe static extern void
Py_SetPythonHome(string home);

The solution appears to be to explicitly marshal the string and hang onto the pointer until it is no longer needed, i.e.

[DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl,
     ExactSpelling = true, CharSet = CharSet.Ansi)]
internal unsafe static extern void
Py_SetPythonHome(IntPtr home);
IntPtr str = Marshal.StringToHGlobalAnsi(@"C:\Python27");
Py_SetPythonHome(str);
// do stuff
Marshal.FreeHGlobal(str);

Running Win7, .Net4.5 and Python 2.7.11.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions