How to use ctypes library with Object Plugin properly?
-
Hello guys!
I need to connect an C lang written lib to make some calculation during getting spline object. Here is a raw example with some details in a comments. Important part: cache created inside lib object. It must be existing during livetime of the Object and free before removing. What is best way to implement this approach? Thx!from ctypes import * class MyPluginData(c4d.plugins.ObjectData): """SomeObject Generator""" self.Init(node, isCloneInit): # It must be called once on object creation and can't be rewritten lib = CDLL('my_lib.so') #or dll on Windows self.Free(node): """ If your class has a destructor it is called as usual after this function. """ # It must be called on system sleep, app close, object deletion etc. # to avoid memory leaks lib.cleanup() self.GetContour(op, doc, lod, bt): """ Here we using lib by calling some lib.foo() and lib.bar()""" # During the execution lib object creates some cache that must be cleaned up after object destruction data = lib.foo() # process data return some_spline
-
-
Hey @mikeudin,
Thank you for reaching out to us. How to use
ctypes
is clearly out of scope of support. I therefore moved your thread. What to do in the context of Cinema 4D with external libraries is also a very wide field and there are no absolute rules.I would recommend having a look at the Python docs itself because they are pretty good in this context: https://docs.python.org/3/library/ctypes.html
- I would avoid loading the shared library with each instance of your plugin (you call
CDLL
in what seems to be meant to be yourNodeData.Init
). That is not only insanely expensive, you might also run into problems with file access. Cinema 4D allocates and deallocates nodes very often. ctypes
has its own threading logic (see docs) which can lead to problems just in standard CPython. The Cinema 4D Python is extra-special when it comes to threading, so you might run there into further problems.- The
ctypes
docs make it a bit look like that you can just magically convert all data from Python to C and back. This is true for atomic types. But for more complex data you will have to usestruct
or the tools ofctypes
(which are just a wrapper aroundstruct
I think). Doing that, converting raw memory manually in Python itself, is not the fastest thing in the world. If you just want to convert a few bytes of data that is okay. But when you have a spline with 2000 points with two tangents each, i.e., 6000 vectors, i.e., 18000 floats, and you want to first push this data into C and then back pull an equally complex result back, AND want to do this in a perfromant manner (the user is scrubbing a parameter slider in your plugin), this can become a bottleneck. Splines are relatively harmless I would say, as it is rare that you produce here truly heavy data, but this could still become a problem.
Maybe @m_adam has something to add here, he knows more about this. But you are on your own here, third party libs and their usage are out of scope of support.
Cheers,
Ferdinand - I would avoid loading the shared library with each instance of your plugin (you call
-
@ferdinand Thank very much! i'll check what can i do.