This one has me really puzzled. I'm trying to use the ctypes library to write binary data to the windows clipboard from within Blender. And it works! Erm... sort of. For some reason, the code fails in one way or another UNLESS I have some random "print" statements scattered between certain statements. The print statements themselves aren't modifying ANY code, they're simply printing out the contents of a variable, or an error code. Commenting out these lines makes the program not work. If I comment out #1, I get an error: "access violation writing 0x000000000000000000000000"... which is DEFINITELY not the address it should be using. Using GetLastError() tells me 8, which according to this: http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx says "not enough memory". That's definitely not true... but I don't know what is causing it to think that. For some reason, having that hexlify function called above it magically makes it work! At least... that statement. Every call to kernel32 or user32 seems to require being separated out by a print statement... or hexlify... or whatever, I don't know!
Anyways, the code is below, with these mysterious print statements marked with hashtags. Note that the first one used to be surrounded by a print statement, but I found it still works if I simply call the function without printing out what it yields. With the remaining 4 statements, I've tried commenting out just the print line, leaving the above assignment to "error" intact -- stopped working. Something about retrieving a variable magically fixes it... or maybe not... I don't have a clue about this. One thing I did try though, and it has me even more puzzled, is I tried running it from IDLE (before, it was all within Blender), and it worked as expected, regardless of prints or not. It's only within Blender that the behavior becomes strange. I've also tried replacing the print statements with "sleep(0.05)", that didn't help.
from ctypes import *
from binascii import *
from struct import *
memcpy = cdll.msvcrt.memcpy
kernel32 = windll.kernel32
user32 = windll.user32
user32.OpenClipboard(None)
user32.EmptyClipboard()
CF_SPARK = user32.RegisterClipboardFormatW("application/spark editor")
GPTR = 0x0040
sampleString = b''
sampleString +=pack('L', 1)
sampleString +=pack('L', 268)
sampleString += b'sheetsmellssheetsmellsbythesheetstore'
#hexlify(sampleString) ########### 1
length = len(sampleString)
memory_handle = kernel32.GlobalAlloc(GPTR,length)
error = kernel32.GetLastError()
print("error= ",error) ########## 2
data_point = kernel32.GlobalLock(memory_handle)
error = kernel32.GetLastError()
print("error= ",error) ########## 3
for i in range(0,length):
value = int.from_bytes((sampleString[i:i+1]), byteorder='little')
memset(data_point+i,value,1)
kernel32.GlobalUnlock(memory_handle)
error = kernel32.GetLastError()
print("error= ",error) ########## 4
user32.SetClipboardData(CF_SPARK,memory_handle)
error = kernel32.GetLastError()
print("error= ",error) ########## 5
user32.CloseClipboard()
BTW, if anybody knows of a better way to write to the clipboard than using memset, that'd be awesome! Note that I can't use strcpy or strncpy because the data I'm attempting to move has nulls in the middle of the data... and that's apparently a bad thing to have with null-terminated strings.
EDIT: Still looking for an answer for this one. I've discovered that I can replace the prints and the hexlify lines with...
hexlify(b'hello')
...and it works just as well. Again, notice the lack of any assignment or declaration. The statement shouldn't be having any kind of effect on the program... yet it is... somehow...