Files
hakril-PythonForWindows/windows/com.py
T
2016-03-24 15:23:15 +01:00

62 lines
2.3 KiB
Python

import struct
import ctypes
import functools
from ctypes.wintypes import HRESULT
from windows.generated_def import interfaces
from windows.generated_def.interfaces import generate_IID, IID
# Simple Implem to create COM Interface in Python (COM -> Python)
def create_c_callable(func, types, keepalive=[]):
func_type = ctypes.WINFUNCTYPE(*types)
c_callable = func_type(func)
# Dirty, but the other method require native code execution
c_callback_addr = ctypes.c_ulong.from_address(id(c_callable._objects['0']) + 3 * ctypes.sizeof(ctypes.c_void_p)).value
keepalive.append(c_callable)
return c_callback_addr
class ComVtable(object):
# Name, types
_funcs_ = [("QueryInterface", [ctypes.HRESULT, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]),
("AddRef", [ctypes.HRESULT, ctypes.c_void_p]),
("Release", [ctypes.HRESULT, ctypes.c_void_p])
]
def __init__(self, **implem_overwrite):
self.implems = []
self.vtable = self._create_vtable(**implem_overwrite)
self.vtable_pointer = ctypes.pointer(self.vtable)
self._as_parameter_ = ctypes.addressof(self.vtable_pointer)
def _create_vtable(self, **implem_overwrite):
vtables_names = [x[0] for x in self._funcs_]
non_expected_args = [func_name for func_name in implem_overwrite if func_name not in vtables_names]
if non_expected_args:
raise ValueError("Non expected function : {0}".format(non_expected_args))
for name, types in self._funcs_:
func_implem = implem_overwrite.get(name)
if func_implem is None:
if hasattr(self, name):
func_implem = getattr(self, name)
else:
raise ValueError("Missing implementation for function <{0}>".format(name))
if isinstance(func_implem, (int, long)):
self.implems.append(func_implem)
else:
self.implems.append(create_c_callable(func_implem, types))
class Vtable(ctypes.Structure):
_fields_ = [(name, ctypes.c_void_p) for name in vtables_names]
return Vtable(*self.implems)
def QueryInterface(self, *args):
return 1
def AddRef(self, *args):
return 1
def Release(self, *args):
return 0