Author: Matti Picus <matti.pi...@gmail.com> Branch: release-pypy3.5-6.x Changeset: r95201:ac3e7351541c Date: 2018-10-07 12:10 +0300 http://bitbucket.org/pypy/pypy/changeset/ac3e7351541c/
Log: add, test LoadLibraryW, LoadLibraryEx{A, W} diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py --- a/rpython/rlib/rwin32.py +++ b/rpython/rlib/rwin32.py @@ -113,6 +113,7 @@ MB_ERR_INVALID_CHARS ERROR_NO_UNICODE_TRANSLATION WC_NO_BEST_FIT_CHARS STD_INPUT_HANDLE STD_OUTPUT_HANDLE STD_ERROR_HANDLE HANDLE_FLAG_INHERIT FILE_TYPE_CHAR + LOAD_WITH_ALTERED_SEARCH_PATH """ from rpython.translator.platform import host_factory static_platform = host_factory() @@ -195,6 +196,22 @@ GetModuleHandle = winexternal('GetModuleHandleA', [rffi.CCHARP], HMODULE) LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], HMODULE, save_err=rffi.RFFI_SAVE_LASTERROR) + def wrap_loadlibraryex(func): + def loadlibrary(name, handle=None, flags=LOAD_WITH_ALTERED_SEARCH_PATH): + # Requires a full path name with '/' -> '\\' + return func(name, handle, flags) + return loadlibrary + + _LoadLibraryExA = winexternal('LoadLibraryExA', + [rffi.CCHARP, HANDLE, DWORD], HMODULE, + save_err=rffi.RFFI_SAVE_LASTERROR) + LoadLibraryExA = wrap_loadlibraryex(_LoadLibraryExA) + LoadLibraryW = winexternal('LoadLibraryW', [rffi.CWCHARP], HMODULE, + save_err=rffi.RFFI_SAVE_LASTERROR) + _LoadLibraryExW = winexternal('LoadLibraryExW', + [rffi.CWCHARP, HANDLE, DWORD], HMODULE, + save_err=rffi.RFFI_SAVE_LASTERROR) + LoadLibraryExW = wrap_loadlibraryex(_LoadLibraryExW) GetProcAddress = winexternal('GetProcAddress', [HMODULE, rffi.CCHARP], rffi.VOIDP) diff --git a/rpython/rlib/test/loadtest/loadtest0.dll b/rpython/rlib/test/loadtest/loadtest0.dll new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9bdcc33a1902f8e989d349c49c2cc08e633aa32b GIT binary patch [cut] diff --git a/rpython/rlib/test/loadtest/loadtest1.dll b/rpython/rlib/test/loadtest/loadtest1.dll new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cb83854875c876717371bdf90488eed9c6571f03 GIT binary patch [cut] diff --git a/rpython/rlib/test/test_rwin32.py b/rpython/rlib/test/test_rwin32.py --- a/rpython/rlib/test/test_rwin32.py +++ b/rpython/rlib/test/test_rwin32.py @@ -6,6 +6,44 @@ from rpython.rlib import rwin32 from rpython.tool.udir import udir +loadtest_dir = os.path.dirname(__file__) + '/loadtest' +test1 = os.path.abspath(loadtest_dir + '/loadtest1.dll') +test0 = os.path.abspath(loadtest_dir + '/loadtest0.dll') + +if not os.path.exists(test1) or not os.path.exists(test0): + # This is how the files, which are checked into the repo, were created + from rpython.translator.tool.cbuild import ExternalCompilationInfo + from rpython.translator.platform import platform + from rpython.translator import cdir + if not os.path.exists(loadtest_dir): + os.mkdir(loadtest_dir) + c_file = udir.ensure("test_rwin32", dir=1).join("test0.c") + c_file.write(py.code.Source(''' + #include "src/precommondefs.h" + RPY_EXPORTED + int internal_sum(int a, int b) { + return a + b; + } + ''')) + eci = ExternalCompilationInfo(include_dirs=[cdir]) + lib_name = str(platform.compile([c_file], eci, test0[:-4], + standalone=False)) + assert os.path.abspath(lib_name) == os.path.abspath(test0) + + c_file = udir.ensure("test_rwin32", dir=1).join("test1.c") + c_file.write(py.code.Source(''' + #include "src/precommondefs.h" + int internal_sum(int a, int b); + RPY_EXPORTED + int sum(int a, int b) { + return internal_sum(a, b); + } + ''')) + eci = ExternalCompilationInfo(include_dirs=[cdir], + libraries=[loadtest_dir + '/loadtest0']) + lib_name = str(platform.compile([c_file], eci, test1[:-4], + standalone=False, )) + assert os.path.abspath(lib_name) == os.path.abspath(test1) def test_get_osfhandle(): fid = open(str(udir.join('validate_test.txt')), 'w') @@ -28,13 +66,13 @@ "import time;" "time.sleep(10)", ], - ) + ) print proc.pid handle = rwin32.OpenProcess(rwin32.PROCESS_ALL_ACCESS, False, proc.pid) assert rwin32.TerminateProcess(handle, signal.SIGTERM) == 1 rwin32.CloseHandle(handle) assert proc.wait() == signal.SIGTERM - + @py.test.mark.dont_track_allocations('putenv intentionally keeps strings alive') def test_wenviron(): name, value = u'PYPY_TEST_日本', u'foobar日本' @@ -55,3 +93,48 @@ msg = rwin32.FormatErrorW(34) assert type(msg) is unicode assert u'%2' in msg + +def test_loadlibraryA(): + # test0 can be loaded alone, but test1 requires the modified search path + hdll = rwin32.LoadLibrary(test0) + assert hdll + faddr = rwin32.GetProcAddress(hdll, 'internal_sum') + assert faddr + assert rwin32.FreeLibrary(hdll) + + hdll = rwin32.LoadLibrary(test1) + assert not hdll + + assert os.path.exists(test1) + + hdll = rwin32.LoadLibraryExA(test1) + assert hdll + faddr = rwin32.GetProcAddress(hdll, 'sum') + assert faddr + assert rwin32.FreeLibrary(hdll) + +def test_loadlibraryW(): + # test0 can be loaded alone, but test1 requires the modified search path + hdll = rwin32.LoadLibraryW(unicode(test0)) + assert hdll + faddr = rwin32.GetProcAddress(hdll, 'internal_sum') + assert faddr + assert rwin32.FreeLibrary(hdll) + + hdll = rwin32.LoadLibraryW(unicode(test1)) + assert not hdll + + assert os.path.exists(unicode(test1)) + + hdll = rwin32.LoadLibraryExW(unicode(test1)) + assert hdll + faddr = rwin32.GetProcAddress(hdll, 'sum') + assert faddr + assert rwin32.FreeLibrary(hdll) + +def test_loadlibrary_unicode(): + import shutil + test0u = unicode(udir.join(u'load\u03betest.dll')) + shutil.copyfile(test0, test0u) + hdll = rwin32.LoadLibraryW(test0u) + assert hdll _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit