Jump to content

swig + hom for custom modules?


Recommended Posts

I want to create a swig-wrapped module that includes functions taking references/pointers to the various HOM_ object types. The goal is to create something that on the Python end interfaces nicely with all of the existing objects in the hom module.

Has anyone been able to get this working? The contents of the HOM headers seems to suggest that I ought to be able to include those in my swig interface to get swig to recognise the hom types/mappings, and then it ought to be able to correctly wrap all of my functions. It looks like I'd at the very least require HOM_Defines.h, but I haven't been able yet to create an interface with that file included that will successfully compile. Problems specific to my swig version, maybe? I've tried 1.3.2 and 2.0.x.

The alternative would be to figure out the PyObject*->HOM_* conversions myself; I know how to do that for swig objects, but not in a way that efficiently determines the correct hom type (I'd have to do introspection using the object description. Lame).

Any pointers would be appreciated.

Edited by Vormav
Link to comment
Share on other sites

...I sort of suspected that I should have added a "other than doing it all in Python" qualifier to my last sentence...

:huh:

EDIT:

So if anyone else needs to do this, here's how you can create a typemap to automatically go from PyObject to a swig wrapped object when your swig interface doesn't know anything about the original wrapped classes:

%typemap(in) Foo* {
    PySwigObject* swigobj = SWIG_Python_GetSwigThis($input);
    if(swigobj)
    {
        if(strcmp(swigobj->ty->name, "_p_Foo") == 0)
            $1 = reinterpret_cast<Foo*>(swigobj->ptr);
        else
            SWIG_exception_fail(SWIG_ValueError, "Expected a Foo* object.");            
    }
    else
        SWIG_exception_fail(SWIG_ValueError, "Expected a swig object.");
}

Similar type maps could be used to go to the original HOM_* types. I'm not thrilled with having to strcmp the class name on every single function call, and I'd still prefer to be able to use the original hom interface. But whatever; this works, and the strcmp probably isn't the bottleneck anyway.

Edited by Vormav
Link to comment
Share on other sites

Alright, so I've figured this out. It is the swig version. In swig versions < 1.3.37, swig used a PySwig naming convention on a lot of symbols. This was flipped around (with good reason) in swig 1.3.37 to be SwigPy. One of the places that this symbol was used was on the type name of the internal swig object. This becomes a problem if you attempt to use swig runtimes from before and after the change within the same python environment; 1.3.37+ can't recognize swig objects < 1.3.37, and HOM just so happens to be using some version < 1.3.37. Also, hom swig interfaces will not compile if used with swig versions as early as 1.3.24.

So the short story: 1.3.36 is the magic swig version number. Works fine without any special typemaps.

EDIT: for clarification, this is with h10.0.528-64

Edited by Vormav
Link to comment
Share on other sites

This is for creating new modules, in c/c++, that are compatible with the types in the hou module.

I.e., take some function like

// foo.h
void Foo(HOM_Node* node)
{
   // do something fancy hdk thing to the node.
   ...
}

wrap in your own swig module:

// foo.i
%import "HOM/HOM_Defines.h"

%{
#include &lt;HOM/HOM_Node.h&gt;
%}

%module foo

void Foo(HOM_Node* node);

process with swig and compile:

swig -c++ -python -classic foo.i
g++ -shared -Wall -I/path/to/python -I/path/to/hdk foo_wrap.cxx -o _foo.so

Now you have a custom module compatible with the hou module. I.e., you can do:

node = hou.node("/path/to/some/node")
imort foo
foo.Foo(node)

Edited by Vormav
Link to comment
Share on other sites

Edward, how familar are you with PY_CPythonAPI? I figured I'd need to throw in HOM_AutoLocks where appropriate, but I'm unsure of whether or not I need swig to spit out code with that extra PY_ prefix. It doesn't look to me like the HOM headers are actually using any of that, unless the standard swig interfaces SESI used are doing the change. For instance, HOM_Defines uses Py_DECREF instead of PY_Py_DECREF, others like PyDict_SetItemString, and so on. It seems like Houdini only ships with one version of Python anyway, so it's not clear to me that this really matters, unless the intent is to be able to create c++ python modules that are compatible with multiple versions of Houdini (which I really don't care about; the internals of my modules are version specific anyway).

Edited by Vormav
Link to comment
Share on other sites

Not really. I'm not sure about your version of PY_CPythonAPI.h, but the comments at the top of my version explain what it is for. ie. They are wrappers that are intended to support multiple versions of Python (which we will see in Houdini 11). In the places where I see PY_ omitted, it is within a SWIGPYTHON define block, which I'm guessing is some special case for swig that doesn't use the PY_ prefix wrappers? <shrugs>

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...