Kipras_ has quit [Read error: Connection reset by peer]
scorpion81 has joined #pypy
<scorpion81>
hello, i am trying to wrap a C++ library (which has a C interface) with CFFI to Python3. i have the sources of this lib and i (still) use ffi.verify() to compile and automatically "check" whether the dll / so has been compiled already. But i ran into a problem under msvc... in order to compile the lib sources + the c interface i resorted to ".cpp" as source_extension
<scorpion81>
but the generated CFFI wrapper file contains implicit casts from void* to other types, which i think is not allowed in C++
<scorpion81>
BUT... if i use .c as extension, the c++ parts of the lib will not compile
<scorpion81>
so, can i... either 1) force something like extern "C" in the generated wrapper or 2) is there some compiler switch in msvc to suppress this implicit cast errors (gcc has -fpermissive) or 3) would it help to use set_source() ? but then i dont have this automatism of compiling and loading the resulting lib any more... (requires manual management)
<scorpion81>
or 4) how can i "embed" a statically .a / .lib into the generated .dll / .so via cffi ? there is ABI and API mode... but this would be some mixture lol
<scorpion81>
or rather... 5) have the cffi wrapper (as source) and a separate .dll / .so, and let the cffi wrapper dlopen it in C ?
<scorpion81>
hello, when i try to compile a cffi binding for a library in C++ (with a c interface), i get with MSVC linker errors with an inline function (implementation is in a .h file) which has static const unsigned int variables defined in the function... the linker does not find those symbols.... must be something with declspec(dllimport) hmmmmmmm.. do i need to modify this code (which is supposed to run on linux too, not
<scorpion81>
this declspec stuff ?
<mattip>
scorpion81: it runs on linux but not on windows?
<mattip>
or is windows your primary dev environment
<mattip>
scorpion81: if I understand correctly, when you export a function so cffi can find it you must use dllexport, not import
<mattip>
dllimport means "don't worry about this function when linking, you will get it at runtime from somewhere else",
<mattip>
but you must tell the linker where that "somewhere else" is by linking in an import library
<mattip>
that says "the function is in this dll, look for it at runtime"
<mattip>
dllexport means "hey linker, create an import library and export this function into it"
<scorpion81>
mattip: it is a bit complicated... it should run on both, but actually it crashes inside the generated cffi .so (somewhere in the library inside) but i need to use msvc combined py/c++ debugger (afaik there is no good equivalent under linux atm) ... i can show you the sources if you wish... it is the "carve" boolean csg library basically
<mattip>
"crashes in the generated cffi" usually means garbage is getting passed in to your function,
<mattip>
or you are not hanging on to cffi.new() references so the memory is made invalid
<scorpion81>
mattip: yup, i wanted to debug this
<scorpion81>
so i can see where the garbage "is" exactly
<mattip>
I have had more luck with printf as the first lines of my dll functions before,
<mattip>
it is hard to get all the debug versions of everything needed for windows to stop in a debugger
<mattip>
debug version of python, debug version of all the c-extensions, debug version of OpenCV or TensorFlow ...
<scorpion81>
math.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""__declspec(dllimport) unsigned int const `cbrt'::`2'::B1" (__imp_?B1@?1??cbrt@@9@4IB)". (that is the linker error)
<scorpion81>
it must be implicitly declspec(dllimport) somehow
<scorpion81>
but maybe i could try printf'ing my way through... hmmm
<mattip>
that looks like a c++ exported symbol, not a c one. Did you use extern "C"?
<scorpion81>
well actually it is C code, yes... i used the "language="c++"" parameter to ffi.verify() lol (i know its deprecated, but i like the automatism of retrieving / caching the generated module / lib object... but the majority of the lib src are c++
<scorpion81>
would i need to put t
<scorpion81>
the extern C as parameter to the code for verify or rather in the .h file where the implementation is ?
<scorpion81>
implementation of "cbrt"...
<scorpion81>
without the language="c++" it wouldnt even have compiled...
<mattip>
h file, but then you need to actually create c interfaces, without namespaces and class instances
<scorpion81>
hold on, i paste you a bit of the interface code ....
<scorpion81>
the "inclusion sequence" is a bit complicated... cbrt.h in win32.h in carve.hpp
<mattip>
does this code work with the MSVC compiler you are using in regular blender?
<mattip>
maybe the compiler is choking on the static const inside an inline function
<scorpion81>
well for some reason it works there... carve is being compiled as static library there
<scorpion81>
with CMake
<scorpion81>
and i can compile that with cmake too, i get a carve.lib then
<scorpion81>
but via cffi / distutils something seems to miss
<mattip>
ok, so use carve.lib, not the source files
<scorpion81>
some "magic" compiler / linker switches... hmm yes... how would i "embed" it into the generated cffi .dll ? can i just link to it and its done automatically ?
<mattip>
yes, instead of using the list of source files, use the library
<scorpion81>
mattip: would i just pass it as "libraries = ["carve.lib"]" argument to ffi.verify() then ?
<mattip>
easier to try it than to look up the incantation, I always forget it if is libraries or extra_libraries or ...
<scorpion81>
mattip: hmm ok, how do i pass the directory where to look for the carve.lib file in ?
<mattip>
either extra_link_args or so, or use os.path to add the explicit path to the name
<scorpion81>
ok, i try /link /LIBPATH:<mypath> as link_args
redj has joined #pypy
<scorpion81>
aah, extra_link_args='/LIBPATH:<mypath' and libraries='carve' did the trick :) now i just need to find the crash lol
<mattip>
scorpion81: it is easier on linux, no need for a special python and blender, you just add a -g flag to cffi compiling and run it under the debugger
<scorpion81>
hmm ok, this entire thing actually is invoked from blender via python nodes, the according node calls ffi.verify and makes the lib object, then executes it with parameters... hmm how would i run this under the debugger ?
* mattip
mumbles about printf ...
<mattip>
on windows, I have added a python breakpoint before the call that fails, then in visual studio "attach to process",
<mattip>
then set a debugger breakpoint, then in the dos console "continue".
<mattip>
I had to compile in release with debug info, so as to not require a special debug version of python.
<mattip>
I had repressed all that knowledge, now it is coming back to me like a bad dream
<scorpion81>
lol i just tried now gdb ./blender... (i built carve with -g and the cffi wrapper also with -g) then i connected the sockets of the node, and bam, now the gdb shows me a source line of the c interface code... wow... didnt think that works lol -> about to fix that now :)
<scorpion81>
(under linux)
<mattip>
see - wasn't that easy :)
<scorpion81>
yes :)
<mattip>
scorpion81: does blender work with PyPy? It would be awesome to benchmark PyPy vs CPython
<scorpion81>
mattip: no i dont think so, they embedded a CPython interpreter
<scorpion81>
probably this would need to be exchanged inside blender
<scorpion81>
CPython out, PyPy in :)
<scorpion81>
mattip: its much faster for me to iterate under linux here... since the windows i run is in a virtualbox and slow as f lol