ctypes libblender

generated ctypes wrapper
http://rpythonic.googlecode.com/files/ctypes_libblender.py

wrapper generator (RPythonic) with precompiled libblender.so for 64bit linux.
http://rpythonic.googlecode.com/files/rpythonic-0.1.5.tar.gz

exposes many functions from the blender C API, over 7,000 lines of generated ctypes wrappers.

Does this work on windows?

Ctypes needs __declspec(dllexport) on every function to work with msvc from what I can determine.

Hi UncleE,
Shouldn’t cmake on Windows take care of __declspec? I’m not sure, but there is nothing in the ctypes wrapper that is linux only, so it should work out of the box if you can compile libblender.dll.
I updated the wrapper so that more functions are exposed, now the main loop can be controled, latest wrapper is here: http://pastebin.com/fhcnpmN3


import os, sys, time
from ctypes_libblender import *
from ctypes import *

def main():
    _argv = ''
    for arg in sys.argv: _argv += arg + ' '
    argc = len(sys.argv)
    argv = ctypes.pointer(ctypes.c_char_p(_argv))
    C = CTX_create()        # bContext pointer
    BLI_threadapi_init()
    RNA_init()
    RE_engines_init()
    pluginapi_force_ref();
    init_nodesystem();
    initglobals()
    IMB_init()
    syshandle = SYS_GetSystem()
    GEN_init_messaging_system()
    ba = BLI_argsInit(argc, argv)
    setupArguments(C, ba, syshandle);
    BLI_argsParse(ba, 1, None, None);        # required, segfaults without this
    sound_init_once();    
    init_def_material();
    print ('WM_init...'); time.sleep(1)
    WM_init(C, argc, argv);                            # some less random crash happening here
    BLI_where_is_temp( c_char_p('/tmp'), 1 )
    CTX_py_init_set(C, 1);
    WM_keymap_init(C);        # (this segfaults if BLI_where_is_temp is not called above)
    time.sleep(1)    # can segfault if we don't wait for the window to appear?
    while True:
        wm_window_process_events(C); 
        wm_event_do_handlers(C);
        wm_event_do_notifiers(C);
        wm_draw_update(C);

Don’t know…

Just know ctypes.CDLL("") doesn’t work in the blender console because none of the symbols are exported which is why I asked.

Well, it does load the blender binary using that method but dll.some_func() just gives a ‘symbol not found’ error.

I’m pretty sure the issue is gcc exports all non-static symbols while msvc only exports the ones you tell it to – which I suppose makes sense if you want an ironclad api or need to protect company secrets.

updated ctypes wrappers, with proper struct and pointers.
http://pastebin.com/f2V3v58z


import os, sys, time
from ctypes_libblender import *
from ctypes import *

def main():
	_argv = ''
	for arg in sys.argv: _argv += arg + ' '
	argc = len(sys.argv)
	argv = ctypes.pointer(ctypes.c_char_p(_argv))
	C = CTX_create()		# bContext pointer
	print('context C', C )
	#segfaults#BLI_where_am_i(c_char_p('blender'), c_char_p('.'));

	BLI_threadapi_init()
	RNA_init()
	RE_engines_init()

	pluginapi_force_ref();
	init_nodesystem();
	initglobals()#;	/* blender.c */

	IMB_init()

	syshandle = SYS_GetSystem()		# not final, only for parsing some command lines
	GEN_init_messaging_system()
	print syshandle

	if 0:
		#/* first test for background */
		ba = BLI_argsInit(argc, argv)#; /* skip binary path */
		setupArguments(C, ba, syshandle);
		BLI_argsParse(ba, 1, None, None);		# required, segfaults without this

	#/* for all platforms, even windos has it! */
	#if(G.background) signal(SIGINT, blender_esc);	/* ctrl c out bg render */
	
	#/* background render uses this font too */
	#BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);

	#/* Initialiaze ffmpeg if built in, also needed for bg mode if videos are rendered via ffmpeg */
	sound_init_once();
	
	init_def_material();

	#if(G.background==0) {
	#BLI_argsParse(ba, 2, None, None);	# some fishy segfault here - seems to happen half of the time
	#BLI_argsParse(ba, 3, None, None);	# WM_init will segfault, seems like some ctypes memory is garbage collected
	print ('WM_init...'); time.sleep(1)
	WM_init(C, argc, argv);		# some less random crash happening here
	print ('WM_init complete')

	#/* this is properly initialized with user defs, but this is default */
	BLI_where_is_temp( c_char_p('/tmp'), 1 ); #/* call after loading the startup.blend so we can read U.tempdir */

	CTX_py_init_set(C, 1);
	## this setups basic mouse and keyboard callbacks ##
	WM_keymap_init(C);		# (this segfaults if BLI_where_is_temp is not called above)

	#/* OK we are ready for it */
	#BLI_argsParse(ba, 4, load_file, C);
	#segfault#BLI_argsFree(ba);
	time.sleep(1)	# can segfault if we don't wait for the window to appear?

	wmPtr = CTX_wm_manager( C )
	wm = wmPtr.contents
	print( wm )
	keymap = wm.defaultconf.contents
	print(keymap)
	wmops = wm.operators
	wmqueue = wm.queue
	print(wmops)
	print(wmqueue)

	print('running mainloop')
	while True:				#WM_main(C);
		#/* get events from ghost, handle window events, add to window queues */
		wm_window_process_events(C); 
		wm_event_do_handlers(C);
		wm_event_do_notifiers(C);
		wm_draw_update(C);

main()


1 Like