VEX error when including an external .vfl/.h file

   4471   3   1
User Avatar
Member
7 posts
Joined: Dec. 2013
Offline
Hello!

I'm having a bit of trouble trying to create a small VEX library for myself, but somehow I can't manage to make it work, I'm hoping someone here can shed a bit of light in the matter.

Basically, any time I try to include any custom file on a wrangle node in Houdini I get this error:

Error:       The sub-network output operator failed to cook: /obj/geo1/attribwrangle1/attribvop1
Warning:     Errors or warnings encountered during VEX compile:
             C:/Users/Supervisor/Documents/houdini15.5/vex/include/a_test.h: Multiple definitions of function: int my_test_func()        (1,14:25).
             Errors or warnings encountered during VEX compile:
             C:/Users/Supervisor/Documents/houdini15.5/vex/include/a_test.h: Multiple definitions of function: int my_test_func()        (1,14:25).
Error:       Vex error: C:/Users/Supervisor/Documents/houdini15.5/vex/include/a_test.h: Multiple definitions of function: int my_test_func()     (1,14:25)
Failed to resolve VEX code op:/obj/geo1/attribwrangle1/attribvop1Unable to load shader 'op:/obj/geo1/attribwrangle1/attribvop1'.

I run Houdini with a different set of environment variables per-project, so I though maybe it was some “HOUDINI_VEX_PATH” or “HOUDINI_PATH” that I forgot to prepend the default environment (&), but I've attempted to do the same with the default Houdini paths and still fails to do such.

To test, I've created a file in CUsers/Supervisor/Documents/houdini15.5/vex/include/a_test.h with this code:
function int my_test_func() {
    return 1;
}

Then in Houdini a simple sphere, a Point Wrangle with the following code:
# include <a_test.h>
i@foo = my_test_func();

I'm not sure what I'm doing wrong, I've even tried to put that same file in $HH/vex/include but it yields the same error.

I'm using Houdini FX 15.5.523 (apprentice) under Windows, I've also attached the full info in the post.

Any ideas?

Thanks.

Attachments:
Houdini_Info.txt (13.2 KB)

User Avatar
Staff
1448 posts
Joined: July 2005
Offline
You may need to guard against re-definition with #ifndef/#endif block. It's a standard practice for including header files such as voplib.h, etc. Try this in your a_test.h file

#ifndef __a_test__
#define __a_test__
function int my_test_func() {
    return 1;
}
#endif
User Avatar
Member
7 posts
Joined: Dec. 2013
Offline
Ok, this works as a charm, thank you very much. I had a look at some .h scripts all around and I noticed the #ifndef, and tried to do it, but I didn't realize it needed an #endif at the bottom.

I've got a couple more questions though, why is it needed to guard against re-definition? Probably is something obvious, but I come from Python and I've never had to deal with this. And secondly, the __a_test__ line, is it just a dummy string to ensure that this code is only executed once, or does it have to match the module name/have some meaningful text?

Thank you!
User Avatar
Staff
1448 posts
Joined: July 2005
Offline
You need it because #include “pastes” the file verbatim thus potentially re-defining functions, etc. Unlike Python's import, the pre-processor does not try to avoid multiple inclusions. https://en.wikipedia.org/wiki/Include_guard [en.wikipedia.org]

The __a_test__ can be arbitrary text, but to ensure (somewhat) uniqueness, the convention is to use the file name.
  • Quick Links