mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
Fix Python 3 crash on Windows, and fix some Python 3-related compile errors
This commit is contained in:
parent
296476f7dd
commit
902bedc314
@ -31,6 +31,9 @@
|
||||
// And this is for GetModuleFileName().
|
||||
#include <windows.h>
|
||||
|
||||
// And this is for CommandLineToArgvW.
|
||||
#include <shellapi.h>
|
||||
|
||||
// SHGetSpecialFolderPath()
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
@ -74,12 +77,11 @@ extern char **environ;
|
||||
#define PREREAD_ENVIRONMENT
|
||||
#endif
|
||||
|
||||
|
||||
// We define the symbol HAVE_GLOBAL_ARGV if we have global variables
|
||||
// named GLOBAL_ARGC/GLOBAL_ARGV that we can read at static init time
|
||||
// to determine our command-line arguments.
|
||||
|
||||
#if defined(HAVE_GLOBAL_ARGV) && defined(PROTOTYPE_GLOBAL_ARGV)
|
||||
#if !defined(WIN32_VC) && defined(HAVE_GLOBAL_ARGV) && defined(PROTOTYPE_GLOBAL_ARGV)
|
||||
extern char **GLOBAL_ARGV;
|
||||
extern int GLOBAL_ARGC;
|
||||
#endif
|
||||
@ -298,7 +300,7 @@ ns_get_environment_variable(const string &var) const {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyGILState_Release(state);
|
||||
|
||||
if (main_dir.empty()) {
|
||||
@ -762,7 +764,32 @@ read_args() {
|
||||
// Next we need to fill in _args, which is a vector containing
|
||||
// the command-line arguments that the executable was invoked with.
|
||||
|
||||
#if defined(IS_FREEBSD)
|
||||
#if defined(WIN32_VC)
|
||||
|
||||
// We cannot rely on __argv when Python is linked in Unicode mode.
|
||||
// Instead, let's use GetCommandLine.
|
||||
|
||||
LPWSTR cmdline = GetCommandLineW();
|
||||
int argc = 0;
|
||||
LPWSTR *argv = CommandLineToArgvW(cmdline, &argc);
|
||||
|
||||
TextEncoder encoder;
|
||||
encoder.set_encoding(Filename::get_filesystem_encoding());
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
wstring wtext(argv[i]);
|
||||
encoder.set_wtext(wtext);
|
||||
|
||||
if (i == 0) {
|
||||
if (_binary_name.empty()) {
|
||||
_binary_name = encoder.get_text();
|
||||
}
|
||||
} else {
|
||||
_args.push_back(encoder.get_text());
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(IS_FREEBSD)
|
||||
// In FreeBSD, we can use sysctl to determine the command-line arguments.
|
||||
|
||||
size_t bufsize = 4096;
|
||||
@ -786,13 +813,17 @@ read_args() {
|
||||
#elif defined(HAVE_GLOBAL_ARGV)
|
||||
int argc = GLOBAL_ARGC;
|
||||
|
||||
if (_binary_name.empty() && argc > 0) {
|
||||
_binary_name = GLOBAL_ARGV[0];
|
||||
// This really needs to be resolved against PATH.
|
||||
}
|
||||
// On Windows, __argv can be NULL when the main entry point is
|
||||
// compiled in Unicode mode (as is the case with Python 3)
|
||||
if (GLOBAL_ARGV != NULL) {
|
||||
if (_binary_name.empty() && argc > 0) {
|
||||
_binary_name = GLOBAL_ARGV[0];
|
||||
// This really needs to be resolved against PATH.
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
_args.push_back(GLOBAL_ARGV[i]);
|
||||
for (int i = 1; i < argc; i++) {
|
||||
_args.push_back(GLOBAL_ARGV[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(HAVE_PROC_SELF_CMDLINE) || defined(HAVE_PROC_CURPROC_CMDLINE)
|
||||
|
@ -3292,6 +3292,21 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj,
|
||||
expected_params += "string";
|
||||
++num_params;
|
||||
|
||||
} else if (TypeManager::is_pointer_to_PyUnicodeObject(type)) {
|
||||
if (args_type == AT_single_arg) {
|
||||
// This is a single-arg function, so there's no need
|
||||
// to convert anything.
|
||||
param_name = "arg";
|
||||
extra_param_check += " && PyUnicode_Check(arg)";
|
||||
} else {
|
||||
indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
|
||||
format_specifiers += "U";
|
||||
parameter_list += ", &" + param_name;
|
||||
}
|
||||
pexpr_string = param_name;
|
||||
expected_params += "unicode";
|
||||
++num_params;
|
||||
|
||||
} else if (TypeManager::is_pointer_to_PyObject(type)) {
|
||||
if (args_type == AT_single_arg) {
|
||||
// This is a single-arg function, so there's no need
|
||||
|
@ -1251,6 +1251,45 @@ is_PyStringObject(CPPType *type) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_pointer_to_PyUnicodeObject
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated type is PyStringObject *.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TypeManager::
|
||||
is_pointer_to_PyUnicodeObject(CPPType *type) {
|
||||
switch (type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_pointer_to_PyUnicodeObject(type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_pointer:
|
||||
return is_PyUnicodeObject(type->as_pointer_type()->_pointing_at);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_PyUnicodeObject
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated type is PyUnicodeObject.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TypeManager::
|
||||
is_PyUnicodeObject(CPPType *type) {
|
||||
switch (type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_PyUnicodeObject(type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_extension:
|
||||
case CPPDeclaration::ST_struct:
|
||||
return (type->get_local_name(&parser) == "PyUnicodeObject");
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_pointer_to_Py_buffer
|
||||
// Access: Public, Static
|
||||
|
@ -96,6 +96,8 @@ public:
|
||||
static bool is_PyObject(CPPType *type);
|
||||
static bool is_pointer_to_PyStringObject(CPPType *type);
|
||||
static bool is_PyStringObject(CPPType *type);
|
||||
static bool is_pointer_to_PyUnicodeObject(CPPType *type);
|
||||
static bool is_PyUnicodeObject(CPPType *type);
|
||||
static bool is_pointer_to_Py_buffer(CPPType *type);
|
||||
static bool is_Py_buffer(CPPType *type);
|
||||
static bool involves_unpublished(CPPType *type);
|
||||
|
@ -221,7 +221,7 @@ def ProgressOutput(progress, msg, target = None):
|
||||
prefix = "%s[%s %d%%%s] " % (GetColor("yellow"), GetColor("cyan"), progress, GetColor("yellow"))
|
||||
else:
|
||||
global THREADS
|
||||
|
||||
|
||||
ident = thread.get_ident()
|
||||
if (ident not in THREADS):
|
||||
THREADS[ident] = len(THREADS) + 1
|
||||
@ -469,7 +469,7 @@ def LocateBinary(binary):
|
||||
p = os.environ["PATH"]
|
||||
|
||||
pathList = p.split(os.pathsep)
|
||||
|
||||
|
||||
if GetHost() == 'windows':
|
||||
if not binary.endswith('.exe'):
|
||||
# Append .exe if necessary
|
||||
@ -871,7 +871,7 @@ def CxxCalcDependencies(srcfile, ipath, ignore):
|
||||
########################################################################
|
||||
|
||||
if sys.platform == "win32":
|
||||
# Note: not supported on cygwin.
|
||||
# Note: not supported on cygwin.
|
||||
if sys.version_info >= (3, 0):
|
||||
import winreg
|
||||
else:
|
||||
@ -1132,7 +1132,7 @@ def GetThirdpartyBase():
|
||||
THIRDPARTYBASE = "thirdparty"
|
||||
if "MAKEPANDA_THIRDPARTY" in os.environ:
|
||||
THIRDPARTYBASE = os.environ["MAKEPANDA_THIRDPARTY"]
|
||||
|
||||
|
||||
return THIRDPARTYBASE
|
||||
|
||||
def GetThirdpartyDir():
|
||||
@ -1853,7 +1853,7 @@ def SdkLocatePython(force_use_sys_executable = False):
|
||||
force_use_sys_executable = False
|
||||
|
||||
if (GetTarget() == 'windows' and not force_use_sys_executable):
|
||||
SDK["PYTHON"] = GetThirdpartyBase()+"/win-python"
|
||||
SDK["PYTHON"] = GetThirdpartyBase() + "/win-python"
|
||||
if (GetOptimize() <= 2):
|
||||
SDK["PYTHON"] += "-dbg"
|
||||
if (GetTargetArch() == 'x64' and os.path.isdir(SDK["PYTHON"] + "-x64")):
|
||||
@ -1882,6 +1882,8 @@ def SdkLocatePython(force_use_sys_executable = False):
|
||||
py_dll = os.path.basename(py_dlls[0])
|
||||
SDK["PYTHONVERSION"] = "python" + py_dll[6] + "." + py_dll[7]
|
||||
|
||||
os.environ["PYTHONHOME"] = SDK["PYTHON"]
|
||||
|
||||
elif CrossCompiling():
|
||||
tp_python = os.path.join(GetThirdpartyDir(), "python")
|
||||
SDK["PYTHON"] = tp_python + "/include"
|
||||
@ -2804,4 +2806,4 @@ def TargetAdd(target, dummy=0, opts=0, input=0, dep=0, ipath=0, winrc=0):
|
||||
t.deps[FindLocation("dtool_have_python.dat", [])] = 1
|
||||
|
||||
if target.endswith(".pz") and not CrossCompiling():
|
||||
t.deps[FindLocation("pzip.exe", [])] = 1
|
||||
t.deps[FindLocation("pzip.exe", [])] = 1
|
||||
|
@ -30,8 +30,13 @@ make(PyUnicodeObject *str) {
|
||||
if (!PyUnicode_CHECK_INTERNED(str)) {
|
||||
// Not an interned string; don't bother.
|
||||
Py_ssize_t len = 0;
|
||||
char *c_str = PyUnicode_AsUTF8AndSize(str, &len);
|
||||
return InternalName::make(name);
|
||||
char *c_str = PyUnicode_AsUTF8AndSize((PyObject *)str, &len);
|
||||
if (c_str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string name(c_str, len);
|
||||
return InternalName::make(c_str, len);
|
||||
}
|
||||
|
||||
InternalName::PyInternTable::const_iterator it;
|
||||
@ -42,7 +47,7 @@ make(PyUnicodeObject *str) {
|
||||
|
||||
} else {
|
||||
Py_ssize_t len = 0;
|
||||
char *c_str = PyUnicode_AsUTF8AndSize(str, &len);
|
||||
char *c_str = PyUnicode_AsUTF8AndSize((PyObject *)str, &len);
|
||||
string name(c_str, len);
|
||||
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user