FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix Py_Main/PySys_SetArgvEx(...) UCS4/PY3 no mem by vmuriart · Pull Request #399 · pythonnet/pythonnet · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .cs  (2) .md  (1) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
1 change: 1 addition & 0 deletions CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
- Fixed wrong version number in `conda.recipe` (#398)
- Fixed fixture location for Python tests and `Embedded_Tests`
- Fixed `PythonException` crash during Shutdown (#400)
- Fixed `Py_Main` & `PySys_SetArgvEx` no mem error on `UCS4/PY3` (#399)

### Removed

Expand Down
5 changes: 0 additions & 5 deletions src/embed_tests/pyinitialize.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ public static void LoadDefaultArgs()
[Test]
public static void LoadSpecificArgs()
{
if (Environment.GetEnvironmentVariable("TRAVIS") == "true" &&
Environment.GetEnvironmentVariable("TRAVIS_PYTHON_VERSION") != "2.7")
{
Assert.Ignore("FIXME: Fails on Travis/PY3+: Fatal Python error: no mem for sys.argv");
}
var args = new[] { "test1", "test2" };
using (new PythonEngine(args))
using (var argv = new PyList(Runtime.Runtime.PySys_GetObject("argv")))
Expand Down
69 changes: 67 additions & 2 deletions src/runtime/runtime.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,41 @@ internal unsafe static extern IntPtr
public unsafe static extern int
Py_Main(
int argc,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] argv
IntPtr lplpargv
);

public static int Py_Main(int argc, string[] argv)
{
// Totally ignoring argc.
argc = argv.Length;

var allStringsLength = 0;
foreach (string x in argv)
{
allStringsLength += x.Length + 1;
}
int requiredSize = IntPtr.Size * argc + allStringsLength * UCS;
IntPtr mem = Marshal.AllocHGlobal(requiredSize);
try
{
// Preparing array of pointers to UTF32 strings.
IntPtr curStrPtr = mem + argc * IntPtr.Size;
for (var i = 0; i < argv.Length; i++)
{
// Unicode or UTF8 work
Encoding enc = UCS == 2 ? Encoding.Unicode : Encoding.UTF32;
byte[] zstr = enc.GetBytes(argv[i] + "\0");
Marshal.Copy(zstr, 0, curStrPtr, zstr.Length);
Marshal.WriteIntPtr(mem + IntPtr.Size * i, curStrPtr);
curStrPtr += zstr.Length;
}
return Py_Main(argc, mem);
}
finally
{
Marshal.FreeHGlobal(mem);
}
}
#elif PYTHON2
[DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl,
ExactSpelling = true, CharSet = CharSet.Ansi)]
Expand Down Expand Up @@ -2087,9 +2120,41 @@ internal unsafe static extern IntPtr
internal unsafe static extern void
PySys_SetArgvEx(
int argc,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] argv,
IntPtr lplpargv,
int updatepath
);

internal static void PySys_SetArgvEx(int argc, string[] argv, int updatepath)
{
// Totally ignoring argc.
argc = argv.Length;

var allStringsLength = 0;
foreach (string x in argv)
{
allStringsLength += x.Length + 1;
}
int requiredSize = IntPtr.Size * argc + allStringsLength * UCS;
IntPtr mem = Marshal.AllocHGlobal(requiredSize);
try
{
// Preparing array of pointers to UTF32 strings.
IntPtr curStrPtr = mem + argc * IntPtr.Size;
for (var i = 0; i < argv.Length; i++)
{
Encoding enc = UCS == 2 ? Encoding.Unicode : Encoding.UTF32;
byte[] zstr = enc.GetBytes(argv[i] + "\0");
Marshal.Copy(zstr, 0, curStrPtr, zstr.Length);
Marshal.WriteIntPtr(mem + IntPtr.Size * i, curStrPtr);
curStrPtr += zstr.Length;
}
PySys_SetArgvEx(argc, mem, updatepath);
}
finally
{
Marshal.FreeHGlobal(mem);
}
}
#elif PYTHON2
[DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl,
ExactSpelling = true, CharSet = CharSet.Ansi)]
Expand Down

Back | FazBrowse Home | New Git URL