I got a dll which expects a memory pointer to a C Type Byte Array. The dll will read and modify the Array and will also put some extra data at the end of the array.
How do I allocate 1MB memory as C Type Byte Array in python and get the pointer?
How can I write my C Type Byte Array in python to this pointer?
You are perhaps wondering why I want to do it this way, but this is unfortunately the only interface to this dll :/ and I have to do this in python.
Here is my current setup:
import ctypes
# Allocate Memory:
BUFFER_LENGTH = 20
# parse to pointer:
bytes_buffer = bytes([0x13, 0x02, 0x03, 0x04, 0x08, 0xA5]) # dummy data
size_in = len(bytes_buffer)
print(bytes_buffer)
# write binary data to memory in CTypes Byte Array
buffer_in = ctypes.cast(bytes_buffer, ctypes.POINTER(ctypes.c_char*BUFFER_LENGTH) )
adr = ctypes.pointer(buffer_in)
address = id(adr)
# get pointer as int32
pointer_data_hi = ctypes.c_uint32(address)
pointer_data_lo = ctypes.c_uint32(address >> 32)
print("in: hi: " + str(pointer_data_hi.value) + ", lo: " + str(pointer_data_lo.value) + ", size: " + str(size_in))
# Load dll
array_modifier = ctypes.windll.LoadLibrary("PythonArrayToDll/modify_array_example/x64/Debug/modify_array_example.dll")
# set pointer of array to dll memory:
array_modifier.setAddrLo(pointer_data_lo)
array_modifier.setAddrHi(pointer_data_hi)
# tell the dll to compute something from the data array:
array_modifier.modifyArray() # this is where it crashes with exception: access violation reading 0xFFFFFFFFFFFFFFFF
# display the results:
for i in range(BUFFER_LENGTH):
print(buffer_in[i].value)
dll code (example):
#include <WinDef.h>
#include "pch.h"
#include "pointer_fnc.h"
#define DLL_EXPORT __declspec(dllexport)
int addrHi;
int addrLo;
extern "C"
{
DLL_EXPORT void setAddrLo(int lo)
{
addrLo = lo;
}
DLL_EXPORT void setAddrHi(int hi)
{
addrHi = hi;
}
DLL_EXPORT void modifyArray()
{
BYTE* my_array = (BYTE*)decode_integer_to_pointer(addrHi, addrLo);
my_array[0] = my_array[0] * 2;
my_array[1] = 2;
my_array[10] = my_array[0];
}
}
with pointer_fnc.cpp providing:
void* decode_integer_to_pointer(int hi, int lo)
{
#if PTRDIFF_MAX == INT64_MAX
union addrconv {
struct {
int lo;
int hi;
} base;
unsigned long long address;
} myaddr;
myaddr.base.lo = lo;
myaddr.base.hi = hi;
return reinterpret_cast<void*>(myaddr.address);
#elif PTRDIFF_MAX == INT32_MAX
return reinterpret_cast<void*>(lo);
#else
#error "Cannot determine 32bit or 64bit environment!"
#endif
}
dll is compiled as a 64 bit and a 64 bit python is used.
I hope you can help me :)