Skip to content

Commit c28e7c4

Browse files
committed
Add CopyComPointerTests.
1 parent f3e7afb commit c28e7c4

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

Lib/test/test_ctypes/test_win32_com_foreign_func.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
raise unittest.SkipTest("Windows-specific test")
1010

1111

12-
from _ctypes import COMError
12+
from _ctypes import COMError, CopyComPointer
1313
from ctypes import HRESULT
1414

1515

@@ -184,5 +184,44 @@ class IPersist(IUnknown):
184184
self.assertEqual(0, ppst.Release())
185185

186186

187+
class CopyComPointerTests(unittest.TestCase):
188+
def setUp(self):
189+
ole32.CoInitializeEx(None, COINIT_APARTMENTTHREADED)
190+
191+
def tearDown(self):
192+
ole32.CoUninitialize()
193+
gc.collect()
194+
195+
def test_copy_com_pointer(self):
196+
class IUnknown(c_void_p):
197+
QueryInterface = proto_query_interface(None, IID_IUnknown)
198+
AddRef = proto_add_ref()
199+
Release = proto_release()
200+
201+
class IPersist(IUnknown):
202+
GetClassID = proto_get_class_id(((OUT, "pClassID"),), IID_IPersist)
203+
204+
src = create_shelllink_persist(IPersist)
205+
dst = IPersist()
206+
207+
self.assertIsNone(dst.value)
208+
with self.assertRaises(ValueError):
209+
dst.GetClassID() # NULL COM pointer access
210+
211+
hr = CopyComPointer(src, byref(dst))
212+
213+
self.assertEqual(S_OK, hr)
214+
self.assertEqual(dst.value, src.value)
215+
216+
clsid = dst.GetClassID()
217+
self.assertEqual(TRUE, is_equal_guid(CLSID_ShellLink, clsid))
218+
219+
# The refcount of a COM pointer created by `CoCreateInstance` is 1.
220+
# `CopyComPointer` calls `AddRef` internally (thus, +1 to the refcount).
221+
# Here, the refcount is decremented from 2 to 1.
222+
self.assertEqual(1, dst.Release())
223+
self.assertEqual(0, src.Release())
224+
225+
187226
if __name__ == '__main__':
188227
unittest.main()

0 commit comments

Comments
 (0)