[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