calling secitemcopymatching in python - python

Tying to read items from Keychain using python (Novice at Mac python)
This is where I have got hacking together several things found in googlepedia
from ctypes import CDll, byref, Structure, POINTER
from Foundation import NSDictionary
class OpaqueObject:
pass
OpaquePtr = POINTER(OpaqueObject)
Security = CDLL('/System/Library......../Security')
query = NSDictionary.dictionaryWithDictionary({<still working on this part>})
items = OpauePtr()
Security.SecItemCopyMatching(query, byref(items))
the {still working on this part}, currently reads {"foo":"bar"} which is of course an invalid query, but it should at least run
anyway it fails on the call of SecItemCopyMatching saying it doent know how to convert param1. I know the the function is defined to take CFDictionary but I expected the toll-free bridging to accept NSDictionary
Anyway I suspect this is all v bad code that is mixing 2 mac python mechanisms ctypes and PyObjc.

Toll-free bridging isn't applicable to Python ctypes. Consider using a CFDictionary instead:
CoreFoundation = CDLL('/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation')
CoreFoundation.CFDictionaryCreateMutable.restype = OpaquePtr
CoreFoundation.CFStringCreateWithBytes.restype = OpaquePtr
def CFDictionaryAddStringKeyValue(d, k, v):
ck = CoreFoundation.CFStringCreateWithBytes(None, k, len(k), 0, 0)
cv = CoreFoundation.CFStringCreateWithBytes(None, v, len(v), 0, 0)
CoreFoundation.CFDictionaryAddValue(d, ck, cv)
CoreFoundation.CFRelease(ck)
CoreFoundation.CFRelease(cv)
query = CoreFoundation.CFDictionaryCreateMutable(None, 0, None, None)
CFDictionaryAddStringKeyValue(query, "foo", "bar")
Then you can just pass query into SecItemCopyMatching.

Related

Trying to get a response from a dll function using ctypes python

I am trying to get a response from a dll library in python using the ctypes wrapper. The response of the function should return x and y coordinates as c_short. A relevant snippet of my code is as follows:
ethdll = ctypes.cdll.LoadLibrary('C:\\Users\\jgallacher\\Documents\\Software_Drivers\\RTC4eth V2 Software Release 2021-06-25\\DLL\\RTC4ethDLLx64.dll')
def get_xy_pos(ethdll):
x = ctypes.c_short()
y = ctypes.c_short()
res = ethdll.get_xy_pos(ctypes.byref(x), ctypes.byref(y))
print(res)
However, when I try this definition I get a Nonetype(0) as the return. Can anyone suggest what is wrong with my function call? I've attached the
I've attached a picture showing the response type to this question thread.
Thanks!
Jordan.
The function returns void, so capturing the return value does nothing. You have created x and y variables to hold the result and need to inspect them after calling the function. Here's a working example with a sample DLL function implementation:
test.c
__declspec(dllexport)
void get_xy_pos(short *xpos, short *ypos) {
*xpos = 5;
*ypos = 7;
}
test.py
import ctypes as ct
dll = ct.CDLL('./test')
# Good practice is to define .argtypes and .restype so ctypes can do type-checking
dll.get_xy_pos.argtypes = ct.POINTER(ct.c_short),ct.POINTER(ct.c_short)
dll.get_xy_pos.restype = None
def get_xy_pos():
x = ct.c_short() # storage for output parameters
y = ct.c_short()
dll.get_xy_pos(ct.byref(x), ct.byref(y)) # pass by reference
return x.value,y.value # inspect the return values
print(get_xy_pos())
Output:
(5, 7)

Causes of Panda3D GeomVertex Writer/Rewriter type error when using the same syntax and object types as in the documentation?

I am completely new to Panda3D on Python and trying to edit a 3D mesh in-place to move its vertices following the user's inputs.
I am using the GeomVertexRewriter or GeomVertexReader + GeomVertexWriter APIs (I tried both), as suggested in the Panda3D documentation here.
However I could not create any GeomVertexWriter (or GeomVertexRewriter which herits from both GeomVertexReader and GeomVertexWriter) object without encountering the following error:
TypeError: Arguments must match:
GeomVertexWriter()
GeomVertexWriter(GeomVertexArrayData array_data)
GeomVertexWriter(GeomVertexData vertex_data)
GeomVertexWriter(Thread current_thread)
GeomVertexWriter(GeomVertexData vertex_data, const InternalName name, Thread current_thread)
GeomVertexWriter(GeomVertexArrayData array_data, int column, Thread current_thread)
GeomVertexWriter(GeomVertexArrayData array_data, Thread current_thread)
GeomVertexWriter(GeomVertexData vertex_data, Thread current_thread)
The error does not happen when I create a GeomVertexReader, and it seems to work perfectly.
Also, my vdata is of the correct type (<class 'panda3d.core.GeomVertexData'>) and prints correctly too (shortened version below):
CatMesh2
949 rows.
Array 0 (0000018310B6A3E0, [ vertex(3f) normal(3f) ]):
row 0:
vertex 1.57086 8.22246 0.487809
normal 0.672279 0.738758 0.0477129
row 1:
vertex 1.69762 8.07273 1.88392
normal 0.748853 0.662674 0.00910493
[...]
row 948:
texcoord 0.249509 0.530177 0
It seems that everywhere I searched, the only way this constructor is ever called is with the very same syntax GeomVertexWriter(vdata, 'vertex') (or 'texcoord'), so I don't really see why this type error occurs.
I tried the following code (that doesn't work):
vertex = GeomVertexRewriter(vdata, 'vertex')
while not vertex.isAtEnd():
v = vertex.getData3()
vertex.setData3(v[0], v[1], 0.0)
>>> File "...\src\geometry_processing.py", line 6, in editVertexData
vertex = GeomVertexRewriter(vdata, 'vertex')
TypeError: Arguments must match:
[...]
Same goes for this one:
vertexW = GeomVertexWriter(vdata, 'vertex')
vertexR = GeomVertexReader(vdata, 'vertex')
v = vertexR.getData3()
vertexW.setData3(v[0], v[1], newVal)
It also happens when I replace 'vertex' with 'texcoord'.
The reader version however works fine:
vertexR = GeomVertexReader(vdata, 'vertex')
v = vertexR.getData3()
print(v)
>>> LVecBase3f(1.57086, 8.22246, 0.487809)
Has anyone ever encountered this error? I have no idea why it occurs even though I am doing the same thing as in the examples in the documentation and in other places. If it was not my mistake, could it be that the vdata from the model I am using is the issue?
How did you obtain the GeomVertexData object? It's possible that you have a "const" version of this object, such as obtained from geom.getVertexData(), but you need a non-const version, such as obtained from geom.modifyVertexData().

Error while calling C DLL function from Python

I'm trying to execute my Python Code that must call a C function, which execute some calculation and save the value in a pointer that must be accessible from Python code. I'd like to do that because i'm constructing a DLL and i want to validate the algebra inside the DLL function, therefore i'd like to use a python code to validate the DLL.
The Python Code
from ctypes import *
if __name__ == '__main__':
mydll = cdll.LoadLibrary("./dll_simples.dll")
funcao = mydll.simuser
funcao.argtypes = c_double,c_double,POINTER(c_double),POINTER(c_double)
a = 0
b = 0
input_1 = (c_double * 1)()
input_1[0] = 5
output_1 = (c_double * 1)()
funcao(a,b,input_1,output_1)
and my DLL
__declspec(dllexport) void simuser(double t, double delt, double* in, double* out)
{
out[0] = 2 * in[0];
}
after executing this code, i have the error
funcao(a,b,input_1,output_1)
OSError: exception: access violation reading 0x0000000000000018
Listing [Python 3.Docs]: ctypes - A foreign function library for Python.
So, you want to pass an array to a function that expects a pointer. For that case, ctypes.cast is required:
So, instead of:
funcao(a, b, input_1, output_1)
use:
funcao(a, b, cast(input_1, POINTER(c_double)), cast(output_1, POINTER(c_double)))
Looking at the existing C code, it only uses one value for the 2 pointers, case in which you won't be needing arrays at all (but I doubt that's the intent because then the input value shouldn't be a pointer):
# ...
input_1 = c_double(5)
output_1 = c_double(0)
funcao(a, b, byref(input_1), byref(output_1))
A working example: [SO]: Pointer from Python (ctypes) to C to save function output (#CristiFati's answer).

How do I pass a byte as reference in Python using ctypes when calling a c++ library?

I've been trying to figure out how to import some c++ functions to python. I got them working until one of the functions needed one of its attributes to be passed by reference and i can't figure out how to make it work.
I've been following the advice given here: https://stackoverflow.com/a/252473/7447849
It's been working perfectly until i tried this one:
I have the following c++ function:
bool __stdcall I2CRead(int Instance, BYTE SlaveAddress, BYTE registerAddress, BYTE* ReadBuff, BYTE Length)
That's the code I've tried:
i2cread_proto = ctypes.WINFUNCTYPE (ctypes.c_bool, ctypes.c_int, ctypes.c_byte, ctypes.c_byte, ctypes.c_byte, ctypes.c_byte)
i2cread_Params = (1, "instance", 0),(1, "SlaveAddress", 0),(1, "registerAddress", 0),(1, "ReadBuff", 0),(1, "Length", 0), # (parameter direction (1 for input, 2 for output), parameter name, default value)
i2cread = i2cread_proto (("I2CRead", qsfp_lib), i2cread_Params)
readBuff = ctypes.c_byte(0)
if (i2cread(0, 160, address, readBuff, 1)==True):
print(readBuff)
else:
print('Could not read data')
This code works but readBuff stays the same default value given instead of changing as it should.
I tried to use byref() but still not working (it gives me an wrong type error).
Any insights on i might be doing wrong? I am not too skilled in Python so maybe there's a concept i'm misunderstanding
Untested. Make sure you use the correct types for arguments.
from ctypes import *
dll = WinDLL('dllname')
dll.I2CRead.argtypes = c_int,c_ubyte,c_ubyte,POINTER(c_ubyte),c_ubyte
dll.I2CRead.restype = c_bool
output = (c_ubyte * 256)() # Create instance of a c_ubyte array to store the output.
result = dll.I2CRead(1,2,3,output,len(output))

Seg faults on c dataypes in python using ctypes

Am very new to ctypes. Trying to use ctypes as I want to play with the libquicktime library to insert text tracks to a movie using python. I'm trying the following and I get seg faults.
I think as the doc says I should be passing ins64_t duration, (in my case random number 123 for tests). Wonder how do I define int64_t var:
>> import ctypes
>> lqt = ctypes.cdll.LoadLibrary('libquicktime.so.0')
>> qth = lqt.quicktime_open('/home/blah/movies/Test.018699.mov', 0, 1)
>> lqt.lqt_add_text_track(qth)
0
>> lqt.lqt_set_text_language(qth, 1, 'eng')
0
>> lqt.lqt_write_text(qth, 1, 'test message', 123)
Segmentation fault
Would be very helpful if someone could explain how do I map such datatypes like (int64, uint64) in python ?
Define the argument types to the function before calling it.
lqt.lqt_write_text.argtypes = [ctypes.c_void_p,ctypes.c_int,ctypes.c_char_p,ctypes.c_int64]
lqt.lqt_write_text.restype = None
lqt.lqt_write_text(qth, 1, 'test message', 123)
Note opaque types like quicktime_t can just substitute a void pointer as the type.
You could use function prototypes to check arguments.
int64_t is ctypes.c_int64.

Categories

Resources