I guessed the following code should work, but it does not. Could someone explain to me how to use this kind of pointer? Of course, this is only a sample code. What I need to solve is to use a pointer that comes from an external library (it has its own allocator 'library_allocete_memory' which is internally using malloc). I need to copy data into that memory from python code.
import ctypes
libc = ctypes.cdll.msvcrt
data = b'test data'
size = len(data)
ptr = libc.malloc(size)
ptr = ctypes.cast(ptr, ctypes.c_char_p)
# ptr = ctypes.create_string_buffer(size) # this is working, but I cannot allocate memory this way in my case
ctypes.memmove(ptr, data, size) # access violation is thrown here
There are 2 things here that (might) generate Undefined Behavior:
According to [Python.Docs]: ctypes - Loading dynamic link libraries (emphasis is mine):
Also mentioning [Python.Docs]: msvcrt - Useful routines from the MS VC++ runtime
[SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer). It's a common pitfall when working with CTypes (calling functions)
Here's a piece of code that works (in a slightly different scenario).
code00.py:
Output:
Notes:
This doesn't generally take care of #1.. It works in my scenario since malloc and free were loaded from the same UCRT instance (cts.cdll.msvcrt). Also, the (aforementioned) UCRT instance is the same as the main one (automatically loaded by the process), but this is just a coincidence, and can't be safely relied on.
I didn't work with WebUI, and I don't know if you could pass it the free memory callback (that way it would be safe to pass current free function), or even signal it not to deallocate the pointer and use the (recommended) cts.create_string_buffer method
Might also be interesting to check:
[SO]: How do I copy a part of bytearray to c_void_p-referenced memory and vice versa? (@CristiFati's answer)
[SO]: Pass str as an int array to a Python C extended function (extended using SWIG) (@CristiFati's answer)
[SO]: How to store a pointer in a custom embedded Python object (@CristiFati's answer)
[SO]: dereferencing the whole Data of c_void_p not only the first byte (@CristiFati's answer)