i am trying to work on easyhook in python and here is my code
# Hook/EasyHook.py
from ctypes import *
from ctypes.util import find_library
from pathlib import Path
c_ulong_p = POINTER(c_ulong)
c_void_pp=POINTER(c_void_p)
res_path = str(Path(__file__).parent / 'res' / 'EasyHook64.dll')
lib_path = find_library(res_path)
clib = cdll.LoadLibrary(lib_path)
class TRACED_HOOK_HANDLE(Structure):
_fields_ = [("Link", c_void_p)]
lh_install_hook = clib.LhInstallHook
lh_install_hook.restype = c_ulong
lh_install_hook.argtypes = [c_void_p, c_void_p, c_void_p, TRACED_HOOK_HANDLE]
# some definition of other functions...
if __name__ == '__main__':
from ctypes.wintypes import *
t_dll = CDLL('User32.dll')
test=lambda:t_dll.MessageBoxW(None, 'hi content!', 'hi title!', 0)
test()
interface=CFUNCTYPE(c_int, HWND, LPCWSTR, LPCWSTR, UINT)
def fake_function(handle, title, message, flag):
return t_original(handle, "hooked "+title, "hooked "+message, flag)
t_hook_info = TRACED_HOOK_HANDLE(None)
if lh_install_hook(t_dll.MessageBoxW, interface(fake_function), None, byref(t_hook_info)):
raise Exception("Hook error[%s]:\n%s" % (rtl_get_last_error(), rtl_get_last_error_string()))
# error occur here and the program terminate
# some other tests...
after a try, it exit on code 0xC0000005 when running to lh_install_hook calling and without any exception printed
then I tried to use those Api after inject into a C++ program by
lh_install_hook(func_address, interface(hook_function), None, byref(hook_info))
where func_address is the actual address of target call,and it cause
python38.dll+24174
_ctypes.pyd+A48D
python38.dll+33E00
python38.dll+3DA6E
_ctypes.pyd+3C69
_ctypes.pyd+38AB
python38.dll+507F5
python38.dll+491C8
is there any way to make it run?
Edit:
here is my code inject and run in the c++ programe
# Hook/__init__.py
from .EasyHook import *
class Hook(object):
def __init__(self, func_address: int):
self.enabled = False
self.hook_info = TRACED_HOOK_HANDLE(None)
self._ACLEntries = (c_ulong * 1)(0)
self.ACLEntries = cast(self._ACLEntries, POINTER(c_ulong))
interface = CFUNCTYPE(self.restype, *self.argtypes)
def hook_function(*args):
return self.hook_function(*args)
if lh_install_hook(func_address, interface(hook_function), None, byref(self.hook_info)):
raise LocalHookError()
# error occur here and the program terminate
# some other codes...
restype = c_void_p
argtypes = []
def hook_function(self, *args):
return self.original(*args)
# main.py
from Hook import Hook
from ctypes import *
from ctypes.wintypes import *
class kernel32_beep_hook(Hook):
restype = c_bool
argtypes = [DWORD,DWORD]
def hook_function(self, a1, a2):
if logger is not None:
logger.log('beep_hook','%s,%s'%(a1,a2))
return self.original(a1,a2)
# some skip codes
addr=kernel32.GetProcAddress(kernel32_module,b"Beep")
ctypes.windll.kernel32.Beep(500,500)
hook=kernel32_beep_hook(addr)
# error occur here and the program terminate
According to [GitHub]: EasyHook/EasyHook - (master) EasyHook/Public/easyhook.h:
typedef struct _HOOK_TRACE_INFO_
{
PLOCAL_HOOK_INFO Link;
}HOOK_TRACE_INFO, *TRACED_HOOK_HANDLE;
TRACED_HOOK_HANDLE is actually a pointer (although its name suggests the opposite), therefore your lh_install_hook.argtypes (1st snippet) is incorrect. It should be:
lh_install_hook.argtypes = [c_void_p, c_void_p, c_void_p, POINTER(TRACED_HOOK_HANDLE)]
Technically, you ran into [SO]: C function called from Python via ctypes returns incorrect value (#CristiFati's answer).
Regarding no exception being thrown, maybe [SO]: Python exception thrown by libtidy is amusingly impossible to catch (#CristiFati's answer) should shed some light.
This should get past the problem, at least the main one. I'm not sure whether there are others, as I didn't install (or build) the .lib, so I didn't run your code. My knowledge is very limited (so this might be complete nonsense), but one potential spot to generate problems is TRACED_HOOK_HANDLE->Link being initialized to NULL.
I posted this question, asking how to get the CPU and GPU temp on Windows 10: Get CPU and GPU Temp using Python Windows. For that question, I didn't include the restriction (at least when I first posted the answer, and for quite a bit after that) for no admin access. I then modified my question to invalidate answers that need admin access (which the only working answer then). A mod rolled back to a previous version of my question, and asked me to post a new question, so I have done that.
I was wondering if there was a way to get the CPU and the GPU temperature in python. I have already found a way for Linux (using psutil.sensors_temperature), and I wanted to find a way for Windows.
Info:
OS: Windows 10
Python: Python 3.8.3 64-bit (So no 32 bit DLLs)
Below are some of the stuff I tried:
When I try doing the below, I get None (from here - https://stackoverflow.com/a/3264262/13710015):
import wmi
w = wmi.WMI()
prin(w.Win32_TemperatureProbe()[0].CurrentReading)
When I try doing the below, I get an error (from here - https://stackoverflow.com/a/3264262/13710015):
import wmi
w = wmi.WMI(namespace="root\wmi")
temperature_info = w.MSAcpi_ThermalZoneTemperature()[0]
print(temperature_info.CurrentTemperature)
Error:
wmi.x_wmi: <x_wmi: Unexpected COM Error (-2147217396, 'OLE error 0x8004100c', None, None)>
When I tried doing the below, I got (from here - https://stackoverflow.com/a/58924992/13710015):
import ctypes
import ctypes.wintypes as wintypes
from ctypes import windll
LPDWORD = ctypes.POINTER(wintypes.DWORD)
LPOVERLAPPED = wintypes.LPVOID
LPSECURITY_ATTRIBUTES = wintypes.LPVOID
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
GENERIC_EXECUTE = 0x20000000
GENERIC_ALL = 0x10000000
FILE_SHARE_WRITE=0x00000004
ZERO=0x00000000
CREATE_NEW = 1
CREATE_ALWAYS = 2
OPEN_EXISTING = 3
OPEN_ALWAYS = 4
TRUNCATE_EXISTING = 5
FILE_ATTRIBUTE_NORMAL = 0x00000080
INVALID_HANDLE_VALUE = -1
FILE_DEVICE_UNKNOWN=0x00000022
METHOD_BUFFERED=0
FUNC=0x900
FILE_WRITE_ACCESS=0x002
NULL = 0
FALSE = wintypes.BOOL(0)
TRUE = wintypes.BOOL(1)
def CTL_CODE(DeviceType, Function, Method, Access): return (DeviceType << 16) | (Access << 14) | (Function <<2) | Method
def _CreateFile(filename, access, mode, creation, flags):
"""See: CreateFile function http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).asp """
CreateFile_Fn = windll.kernel32.CreateFileW
CreateFile_Fn.argtypes = [
wintypes.LPWSTR, # _In_ LPCTSTR lpFileName
wintypes.DWORD, # _In_ DWORD dwDesiredAccess
wintypes.DWORD, # _In_ DWORD dwShareMode
LPSECURITY_ATTRIBUTES, # _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes
wintypes.DWORD, # _In_ DWORD dwCreationDisposition
wintypes.DWORD, # _In_ DWORD dwFlagsAndAttributes
wintypes.HANDLE] # _In_opt_ HANDLE hTemplateFile
CreateFile_Fn.restype = wintypes.HANDLE
return wintypes.HANDLE(CreateFile_Fn(filename,
access,
mode,
NULL,
creation,
flags,
NULL))
handle=_CreateFile('\\\\\.\PhysicalDrive0',GENERIC_WRITE,FILE_SHARE_WRITE,OPEN_EXISTING,ZERO)
def _DeviceIoControl(devhandle, ioctl, inbuf, inbufsiz, outbuf, outbufsiz):
"""See: DeviceIoControl function
http://msdn.microsoft.com/en-us/library/aa363216(v=vs.85).aspx
"""
DeviceIoControl_Fn = windll.kernel32.DeviceIoControl
DeviceIoControl_Fn.argtypes = [
wintypes.HANDLE, # _In_ HANDLE hDevice
wintypes.DWORD, # _In_ DWORD dwIoControlCode
wintypes.LPVOID, # _In_opt_ LPVOID lpInBuffer
wintypes.DWORD, # _In_ DWORD nInBufferSize
wintypes.LPVOID, # _Out_opt_ LPVOID lpOutBuffer
wintypes.DWORD, # _In_ DWORD nOutBufferSize
LPDWORD, # _Out_opt_ LPDWORD lpBytesReturned
LPOVERLAPPED] # _Inout_opt_ LPOVERLAPPED lpOverlapped
DeviceIoControl_Fn.restype = wintypes.BOOL
# allocate a DWORD, and take its reference
dwBytesReturned = wintypes.DWORD(0)
lpBytesReturned = ctypes.byref(dwBytesReturned)
status = DeviceIoControl_Fn(devhandle,
ioctl,
inbuf,
inbufsiz,
outbuf,
outbufsiz,
lpBytesReturned,
NULL)
return status, dwBytesReturned
class OUTPUT_temp(ctypes.Structure):
"""See: http://msdn.microsoft.com/en-us/library/aa363972(v=vs.85).aspx"""
_fields_ = [
('Board Temp', wintypes.DWORD),
('CPU Temp', wintypes.DWORD),
('Board Temp2', wintypes.DWORD),
('temp4', wintypes.DWORD),
('temp5', wintypes.DWORD)
]
class OUTPUT_volt(ctypes.Structure):
"""See: http://msdn.microsoft.com/en-us/library/aa363972(v=vs.85).aspx"""
_fields_ = [
('VCore', wintypes.DWORD),
('V(in2)', wintypes.DWORD),
('3.3V', wintypes.DWORD),
('5.0V', wintypes.DWORD),
('temp5', wintypes.DWORD)
]
def get_temperature():
FUNC=0x900
outDict={}
ioclt=CTL_CODE(FILE_DEVICE_UNKNOWN, FUNC, METHOD_BUFFERED, FILE_WRITE_ACCESS)
handle=_CreateFile('\\\\\.\PhysicalDrive0',GENERIC_WRITE,FILE_SHARE_WRITE,OPEN_EXISTING,ZERO)
win_list = OUTPUT_temp()
p_win_list = ctypes.pointer(win_list)
SIZE=ctypes.sizeof(OUTPUT_temp)
status, output = _DeviceIoControl(handle, ioclt , NULL, ZERO, p_win_list, SIZE)
for field, typ in win_list._fields_:
#print ('%s=%d' % (field, getattr(disk_geometry, field)))
outDict[field]=getattr(win_list,field)
return outDict
def get_voltages():
FUNC=0x901
outDict={}
ioclt=CTL_CODE(FILE_DEVICE_UNKNOWN, FUNC, METHOD_BUFFERED, FILE_WRITE_ACCESS)
handle=_CreateFile('\\\\\.\PhysicalDrive0',GENERIC_WRITE,FILE_SHARE_WRITE,OPEN_EXISTING,ZERO)
win_list = OUTPUT_volt()
p_win_list = ctypes.pointer(win_list)
SIZE=ctypes.sizeof(OUTPUT_volt)
status, output = _DeviceIoControl(handle, ioclt , NULL, ZERO, p_win_list, SIZE)
for field, typ in win_list._fields_:
#print ('%s=%d' % (field, getattr(disk_geometry, field)))
outDict[field]=getattr(win_list,field)
return outDict
print(OUTPUT_temp._fields_)
Output:
[('Board Temp', <class 'ctypes.c_ulong'>), ('CPU Temp', <class 'ctypes.c_ulong'>), ('Board Temp2', <class 'ctypes.c_ulong'>), ('temp4', <class 'ctypes.c_ulong'>), ('temp5', <class 'ctypes.c_ulong'>)]
I tried this code, and it worked, but it needs admin (from here - https://stackoverflow.com/a/62936850/13710015):
import clr # the pythonnet module.
clr.AddReference(r'YourdllPath')
from OpenHardwareMonitor.Hardware import Computer
c = Computer()
c.CPUEnabled = True # get the Info about CPU
c.GPUEnabled = True # get the Info about GPU
c.Open()
while True:
for a in range(0, len(c.Hardware[0].Sensors)):
# print(c.Hardware[0].Sensors[a].Identifier)
if "/intelcpu/0/temperature" in str(c.Hardware[0].Sensors[a].Identifier):
print(c.Hardware[0].Sensors[a].get_Value())
c.Hardware[0].Update()
I tried this code, but it also needed admin (from here - https://stackoverflow.com/a/49909330/13710015):
import clr #package pythonnet, not clr
openhardwaremonitor_hwtypes = ['Mainboard','SuperIO','CPU','RAM','GpuNvidia','GpuAti','TBalancer','Heatmaster','HDD']
cputhermometer_hwtypes = ['Mainboard','SuperIO','CPU','GpuNvidia','GpuAti','TBalancer','Heatmaster','HDD']
openhardwaremonitor_sensortypes = ['Voltage','Clock','Temperature','Load','Fan','Flow','Control','Level','Factor','Power','Data','SmallData']
cputhermometer_sensortypes = ['Voltage','Clock','Temperature','Load','Fan','Flow','Control','Level']
def initialize_openhardwaremonitor():
file = 'OpenHardwareMonitorLib.dll'
clr.AddReference(file)
from OpenHardwareMonitor import Hardware
handle = Hardware.Computer()
handle.MainboardEnabled = True
handle.CPUEnabled = True
handle.RAMEnabled = True
handle.GPUEnabled = True
handle.HDDEnabled = True
handle.Open()
return handle
def initialize_cputhermometer():
file = 'CPUThermometerLib.dll'
clr.AddReference(file)
from CPUThermometer import Hardware
handle = Hardware.Computer()
handle.CPUEnabled = True
handle.Open()
return handle
def fetch_stats(handle):
for i in handle.Hardware:
i.Update()
for sensor in i.Sensors:
parse_sensor(sensor)
for j in i.SubHardware:
j.Update()
for subsensor in j.Sensors:
parse_sensor(subsensor)
def parse_sensor(sensor):
if sensor.Value is not None:
if type(sensor).__module__ == 'CPUThermometer.Hardware':
sensortypes = cputhermometer_sensortypes
hardwaretypes = cputhermometer_hwtypes
elif type(sensor).__module__ == 'OpenHardwareMonitor.Hardware':
sensortypes = openhardwaremonitor_sensortypes
hardwaretypes = openhardwaremonitor_hwtypes
else:
return
if sensor.SensorType == sensortypes.index('Temperature'):
print(u"%s %s Temperature Sensor #%i %s - %s\u00B0C" % (hardwaretypes[sensor.Hardware.HardwareType], sensor.Hardware.Name, sensor.Index, sensor.Name, sensor.Value))
if __name__ == "__main__":
print("OpenHardwareMonitor:")
HardwareHandle = initialize_openhardwaremonitor()
fetch_stats(HardwareHandle)
print("\nCPUMonitor:")
CPUHandle = initialize_cputhermometer()
fetch_stats(CPUHandle)
I am also fine with using C/C++ extensions with Python, portable command-line apps (which will be run with subprocess.Popen), DLLs, and commands (which will be run with subprocess.Popen).
Non-portable apps are not allowed.
Problem
An unprivileged user needs access to functionality only available by a privileged user in a secure manner.
Solution
Create an server-client interface where functionality is decoupled from the actual system as to prevent security issues (ie: don't just pipe commands or options directly from client for execution by the server).
Consider using gRPC for this server-client interface. If you haven't used gRPC before, here's an example of what this entails:
Create a temperature.proto:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "temperature";
option java_outer_classname = "TemperatureProto";
option objc_class_prefix = "TEMP";
package temperature;
service SystemTemperature {
rpc GetTemperature (TemperatureRequest) returns (TemperatureReply) {}
}
message TemperatureRequest {
string name = 1;
}
message TemperatureReply {
string message = 1;
}
Compile the aforementioned with protoc from protobuf library.
python -m grpc_tools.protoc --proto_path=. temperature.proto --python_out=. --grpc_python_out=.
This will generate a file named temperature_pb2_grpc.py, which is where you'll define functionality and response for GetTemperature, note, that you can implement logic branches contextual upon TemperatureRequest options passed from the client.
Once complete simply write and run a temperature_server.py from your privileged user, and temperature_client.py from your unprivileged user.
References
gRPC: https://grpc.io
gRPC QuickStart guide: https://grpc.io/docs/languages/ruby/quickstart/
protobuf: https://developers.google.com/protocol-buffers/
This modifies the registry, use at your own risk. This modifies the reg key Software\Classes\ms-settings\shell\open\command, so take a backup of it.
This works with python:
step1: Turn off the antivirus protection (I don't know how to do that by automation)
step2: Download this repository - https://github.com/YashMakan/get_cpu_gpu_details
step3: Extract the files
step4: Open app.py file
step5: change the variable "file" with the complete path of therm.py, example - C:\\...\\therm.py
step6: Run app.py
step7: You will get the details
I am trying to capture the screen using only the ctypes modules. Unfortunately it ends on a segmentation fault. Argtypes and restypes are set correctly, I think. This is the code which crashes:
#!/usr/bin/env python
# coding: utf-8
from sys import maxsize
from ctypes import POINTER, Structure, c_double, byref, c_int32, c_uint32, c_float, cdll
from ctypes.util import find_library
# For tests only
from Quartz import CGDisplayBounds
CGFloat = c_double if maxsize > 2 ** 32 else c_float
class CGPoint(Structure):
_fields_ = [('x', CGFloat), ('y', CGFloat)]
class CGSize(Structure):
_fields_ = [('width', CGFloat), ('height', CGFloat)]
class CGRect(Structure):
_fields_ = [('origin', CGPoint), ('size', CGSize)]
def __repr__(self):
''' With or without this method, segfault. '''
ret = (self.origin.x, self.origin.y, self.size.width, self.size.height)
return ret.__repr__()
# Library
cgs = cdll.LoadLibrary(find_library('CoreGraphics'))
# Argtypes
cgs.CGGetActiveDisplayList.argtypes = \
[c_uint32, POINTER(c_uint32), POINTER(c_uint32)]
cgs.CGDisplayBounds.argtypes = [c_uint32]
# Restypes
cgs.CGGetActiveDisplayList.restypes = c_int32
cgs.CGDisplayBounds.restypes = CGRect
# Monitors
max_displays = 32
display_count = c_uint32(0)
active_displays = (c_uint32 * max_displays)()
cgs.CGGetActiveDisplayList(max_displays, active_displays, byref(display_count))
for idx in range(display_count.value):
display = active_displays[idx]
# This line works
print(CGDisplayBounds(display))
# SEGFAULT HERE!!!!
rect = cgs.CGDisplayBounds(display)
print(rect)
MacOS X version 10.11.3.
Python versions 2.7.10 and 2.6.9.
... Sorry, the error is when setting restype. There is a trailing "s".
The line :
cgs.CGDisplayBounds.restypes = CGRect
Should be:
cgs.CGDisplayBounds.restype = CGRect
I'm developing instrument drivers for testing at work. It's first developed in
C using the IVI/Visa standard. I am then using a python wrapper for a dll of the C to use the functions in the python environment. However with the current one I am getting an error:
Traceback (most recent call last):
File "D:/CAS/Development/LvDrivers/Python/Python_wrapper/ADIag81110a.py", line 1362, in <module>
PGEN.ConfigureTransitionCoupling(1, "1")
File "D:/CAS/Development/LvDrivers/Python/Python_wrapper/ADIag81110a.py", line 1305, in ConfigureTransitionCoupling
ADIag81110aLib().ADIag81110a_ConfigureTransitionCoupling( self.vi, transitionEnabling , channelName )
WindowsError: exception: access violation reading 0x00000031
It happens with any function I use from the C. All of the functions work correctly when they are ran directly in C. He is is the C definition of that function:
ViStatus _VI_FUNC ADIag81110a_ConfigureTransitionCoupling (ViSession vi,
ViInt32 transitionEnabling, ViChar channelName[])
{
ViStatus error = VI_SUCCESS;
checkErr( Ivi_LockSession (vi, VI_NULL));
viCheckParm(Ivi_SetAttributeViInt32 (vi, channelName, ADIAG81110A_ATTR_TRANSITION_COUPLING,
0, transitionEnabling), 2, "Transition Coupling");
Error:
Ivi_UnlockSession (vi, VI_NULL);
return error;
}
The python might seem a little complicated but i'll only be posting the code that I feel is relevant to declaration of the ConfigureTransitionCoupling function that I'm using as an example and the ctypes declarations:
import os
import visa_exceptions
from visa_messages import completion_and_error_messages
from vpp43_constants import *
from vpp43_types import *
from ctypes import cdll
if os.name == 'nt':
from ctypes import windll
else:
from ctypes import CFUNCTYPE as FUNCTYPE
import warnings
class Singleton(object):
def __new__(cls, *args, **kwds):
it = cls.__dict__.get("__it__")
if it is not None:
return it
cls.__it__ = it = object.__new__(cls)
it.init(*args, **kwds)
return it
class ADIag81110a_lib(Singleton):
def __call__(self, force_cdecl=False):
if self.__lib is None or self.__cdecl_lib is None:
self.load_library()
if force_cdecl:
return self.__cdecl_lib
return self.__lib
def init(self):
self.__lib = self.__cdecl_lib = None
def load_library(self, path=None):
if os.name == 'nt':
path = "C:\Program Files (x86)\IVI Foundation\IVI\Bin\ADIag81110a_32.dll"
self.__lib = windll.LoadLibrary(path)
self.__cdecl_lib = cdll.LoadLibrary(path)
elif os.name == 'posix':
if not path:
path = "please put path to unix/linix here"
self.__lib = self.__cdecl_lib = cdll.LoadLibrary(path)
else:
self.__lib = self.__cdecl_lib = None
raise visa_exceptions.OSNotSupported, os.name
self.__initialize_library_functions()
return None
def __initialize_library_functions(self):
self.__set_argument_types("ADIag81110a_ConfigureTransitionCoupling", [ ViSession , ViInt32 , ViChar ])
def __set_argument_types(self, inst_function, types, force_cdecl=False, may_be_missing=True):
if force_cdecl:
library = self.__cdecl_lib
else:
library = self.__lib
try:
getattr(library, inst_function).argtypes = types
except AttributeError:
if not may_be_missing:
raise
ADIag81110aLib = ADIag81110a_lib()
class ADIag81110a():
def ConfigureTransitionCoupling(self , transitionEnabling , channelName ):
ADIag81110aLib().ADIag81110a_ConfigureTransitionCoupling( self.vi, transitionEnabling , channelName )
if __name__ == '__main__':
#This initilises the communication with the instrument
PGEN = ADIag81110a("GPIB0::10::INSTR")
test = PGEN.ReadOutputImpedance("1")
print test
I have looked at other people posting about their error and I feel they are using C-types in a different way to me so I am unable to apply their solutions.
Any help is appreciated. This is also my first post on stack overflow so feel free to point out any issues with my post :)
I've been trying to use the digi Advanced Device Discovery protocol library with python using ctypes.
the context:
Windows 7 x64
python 2.7.5
dll library
here's my current code:
guid = (0xbf6db409,0xc83d,0x44a3,0xa3,0x6d,0x21,0x79,0x7d,0x2f,0x73,0xf9)
class ADDP():
from ctypes import Structure
class GUID(Structure):
from ctypes.wintypes import DWORD,WORD,BYTE
_fields_ = [("Data1",DWORD),
("Data2",WORD),
("Data3",WORD),
("Data4",BYTE * 8)]
def __init__(self, guid):
from ctypes import windll, c_void_p, c_byte, pointer,c_char,POINTER
from ctypes.wintypes import HANDLE
import ctypes
self.dll = windll.LoadLibrary("D:\\Lib\\addp.dll")
self.guid = self.GUID()
self.guid.Data1 = guid[0]
self.guid.Data2 = guid[1]
self.guid.Data3 = guid[2]
self.guid.Data4 = (c_byte * 8)(guid[3],guid[4],guid[5],guid[6],guid[7],guid[8],guid[9],guid[10])
addpopen = self.dll[1]
addpopen.argtypes = [POINTER(self.GUID),]
addpopen.restype = c_void_p
#print addpopen.restype
self.handler = addpopen(pointer(self.guid))
if self.handler == None:
raise RuntimeError()
self.opened = False
else:
self.opened = True
def isOpen(self):
return self.opened
def Discover(self):
from ctypes import c_int
srch = self.dll[6]
srch.restype = c_int
print srch(self.handler,10,10)
def Close(self):
close = self.dll[3]
close.restype = None
self.opened = False
#print close(self.handler)
conn = ADDP(guid)
#print conn.handler
conn.Discover()
#conn.Close()
print conn.handler
i searched a lot for how to handle a handle returned from a c function, but couldn't find much about it, i read the ctypes docs for a while, and then inspected the header file too..
the handle is defined in the header file with
typedef void* addp_handle_t;
so i assumed i had to set 'restype' to 'c_void_p', the function always returns 'None'
its specified in the header file that it returns 'None' when an error has occurred, else it return the handle to ADDP session.
another thing, this dll does not export functions by name... i had to, more or less, guess what function is what by expected bytes in arguments.
any ideas on this?
i've found a project on google code but apparently it didn't go far...
if you need any other details, just say