[pypy-commit] pypy default: add, test LoadLibraryW, LoadLibraryEx{A, W}

mattip pypy.commits at gmail.com
Sun Oct 7 06:23:24 EDT 2018


Author: Matti Picus <matti.picus at gmail.com>
Branch: 
Changeset: r95180:80ba133be397
Date: 2018-10-07 12:10 +0300
http://bitbucket.org/pypy/pypy/changeset/80ba133be397/

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


More information about the pypy-commit mailing list