A simple example:
extern "C" { struct MyStruct { int integer_field; char* null_terminated_string; }; __declspec(dllexport) void MyFunc(MyStruct* structure_array, int length); } The function itself is empty and does nothing:
#include <iostream> #include "Header.h" __declspec(dllexport) void MyFunc(MyStruct* structure_array, int length) { for (auto i = 0; i < length; i++) { // printf("%d", structure_array[i].integer_field); } } Python:
from ctypes import c_char_p, POINTER, c_int, c_float, Structure, WINFUNCTYPE, windll, byref, cast import time class MyStruct(Structure): _fields_ = (("integer_field", c_int), ("null_terminated_string", c_char_p)) def __init__(self, intf, strf): super().__init__(intf, strf) struc_pointer = POINTER(MyStruct) # или cdll.Load ... lib = windll.LoadLibrary('x64dll.dll') MyFunc = lib.MyFunc MyFunc.restype = None MyFunc.argtypes = (struc_pointer, c_int) struc = MyStruct(666, b"satan") struc2 = MyStruct(777, b"lucky") lst = [struc, struc2] TIMES = 10 ** 6 start = time.clock() my_c_array = (MyStruct * len(lst))(*lst) for i in range(TIMES): MyFunc(my_c_array, len(lst)) print("TOTAL:", time.clock() - start, "sec") print("1 call:", format(((time.clock() - start) / TIMES) * 10 ** 6, ".3f"), "microsec") >>> TOTAL: 1.0535024347466948 sec >>> 1 call: 1.054 microsec Whole microsecond to challenge? Call an empty function? What is so complicated at this time and why is call time not measured in nanoseconds?
In an amicable way, you need not to cache my_c_array and transfer it to the function call:
MyFunc((MyStruct * len(lst))(*lst), len(lst)) and then with increasing the length of the list, everything becomes unacceptably bad.