-
-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement record pointers as method parameters of a Dispatch Interface (
#535) * Implement record pointers as method parameters of a Dispatch Interface to get server side modifications of a record marshaled back to the client. * Adding the source files for a simple out of process COM-server under 'source/OutProcSrv'. The COM-server implements a dual interface and the corresponding dispinterface with currently just a single method 'InitRecord' for testing record pointer parameters. The added unittest 'test_dispifc_recordptr.py' passes a record by reference and also as a record pointer to the 'InitRecord' method of the dispinterface and checks the initialized records. * Modified the testing workflow to compile the out of process COM-server and register it. * Added test for passing a record as a pure [in] parameter. * Apply suggestions from code review Co-authored-by: Jun Komoda <[email protected]> * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Jun Komoda <[email protected]> * Commit for renaming. Changed the names of: - Interfaces - Component - ProgID - Type Library Renamed the source files of the C++ server component to reflect the component name. Changed the name of the C++ COM server sources subdirectory. * Renamed the structure used for record parameter testing. * Fixed typo that rendered a subtest useless. * Apply suggestions from code review --------- Co-authored-by: Jun Komoda <[email protected]>
- Loading branch information
Showing
17 changed files
with
2,157 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# coding: utf-8 | ||
|
||
import unittest | ||
|
||
from comtypes import CLSCTX_LOCAL_SERVER | ||
from comtypes.client import CreateObject, GetModule | ||
from ctypes import byref, pointer | ||
|
||
ComtypesCppTestSrvLib_GUID = "{07D2AEE5-1DF8-4D2C-953A-554ADFD25F99}" | ||
|
||
try: | ||
GetModule((ComtypesCppTestSrvLib_GUID, 1, 0, 0)) | ||
import comtypes.gen.ComtypesCppTestSrvLib as ComtypesCppTestSrvLib | ||
|
||
IMPORT_FAILED = False | ||
except (ImportError, OSError): | ||
IMPORT_FAILED = True | ||
|
||
|
||
@unittest.skipIf(IMPORT_FAILED, "This depends on the out of process COM-server.") | ||
class Test_DispMethods(unittest.TestCase): | ||
"""Test dispmethods with record and record pointer parameters.""" | ||
|
||
EXPECTED_INITED_QUESTIONS = "The meaning of life, the universe and everything?" | ||
|
||
def _create_dispifc(self) -> "ComtypesCppTestSrvLib.IDispRecordParamTest": | ||
# Explicitely ask for the dispinterface of the component. | ||
return CreateObject( | ||
"Comtypes.DispIfcParamTests", | ||
clsctx=CLSCTX_LOCAL_SERVER, | ||
interface=ComtypesCppTestSrvLib.IDispRecordParamTest, | ||
) | ||
|
||
def test_inout_byref(self): | ||
dispifc = self._create_dispifc() | ||
# Passing a record by reference to a method that has declared the parameter | ||
# as [in, out] we expect modifications of the record on the server side to | ||
# also change the record on the client side. | ||
test_record = ComtypesCppTestSrvLib.StructRecordParamTest() | ||
self.assertEqual(test_record.question, None) | ||
self.assertEqual(test_record.answer, 0) | ||
self.assertEqual(test_record.needs_clarification, False) | ||
dispifc.InitRecord(byref(test_record)) | ||
self.assertEqual(test_record.question, self.EXPECTED_INITED_QUESTIONS) | ||
self.assertEqual(test_record.answer, 42) | ||
self.assertEqual(test_record.needs_clarification, True) | ||
|
||
def test_inout_pointer(self): | ||
dispifc = self._create_dispifc() | ||
# Passing a record pointer to a method that has declared the parameter | ||
# as [in, out] we expect modifications of the record on the server side to | ||
# also change the record on the client side. | ||
test_record = ComtypesCppTestSrvLib.StructRecordParamTest() | ||
self.assertEqual(test_record.question, None) | ||
self.assertEqual(test_record.answer, 0) | ||
self.assertEqual(test_record.needs_clarification, False) | ||
dispifc.InitRecord(pointer(test_record)) | ||
self.assertEqual(test_record.question, self.EXPECTED_INITED_QUESTIONS) | ||
self.assertEqual(test_record.answer, 42) | ||
self.assertEqual(test_record.needs_clarification, True) | ||
|
||
def test_in_record(self): | ||
# Passing a record to a method that has declared the parameter just as [in] | ||
# we expect modifications of the record on the server side NOT to change | ||
# the record on the client side. | ||
# We also need to test if the record gets properly passed to the method on | ||
# the server side. For this, the 'VerifyRecord' method returns 'True' if | ||
# all record fields have values equivalent to the initialization values | ||
# provided by 'InitRecord'. | ||
inited_record = ComtypesCppTestSrvLib.StructRecordParamTest() | ||
inited_record.question = self.EXPECTED_INITED_QUESTIONS | ||
inited_record.answer = 42 | ||
inited_record.needs_clarification = True | ||
for rec, expected, (q, a, nc) in [ | ||
(inited_record, True, (self.EXPECTED_INITED_QUESTIONS, 42, True)), | ||
# Also perform the inverted test. For this, create a blank record. | ||
(ComtypesCppTestSrvLib.StructRecordParamTest(), False, (None, 0, False)), | ||
]: | ||
with self.subTest(expected=expected, q=q, a=a, nc=nc): | ||
# Perform the check on initialization values. | ||
self.assertEqual(self._create_dispifc().VerifyRecord(rec), expected) | ||
self.assertEqual(rec.question, q) | ||
# Check if the 'answer' field is unchanged although the method | ||
# modifies this field on the server side. | ||
self.assertEqual(rec.answer, a) | ||
self.assertEqual(rec.needs_clarification, nc) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
Oops, something went wrong.