Problems with 0.6.0 header files on Windows Visual Studio 2015

286 views
Skip to first unread message

raypend...@gmail.com

unread,
May 12, 2017, 9:20:02 PM5/12/17
to Cap'n Proto
I'm trying to get Cap'n Proto 0.6.0 compiled as a plugin under UnrealEngine 4.13 using Visual Studio 2015 (update 3). I have compiled this version under Visual Studio from source. To test, if I create just a plain C++ project and use the installed Cap'n headers and libraries I can generate test message classes that seem to compile with a few compiler warnings. However when compiling an Unreal Project (or a Win32 project) with these same classes I get all sorts of strange errors in kj and cap'n (common.h, etc.) as it imports the header files. My best guess is that it has something to do with the precompiled headers in those environments? Does anyone have a clue or have any advice using Cap'n Proto under Unreal Engine/ Windows?

Example of the errors:

thirdparty\capnproto\include\capnp\common.h(64): error C2628: 'capnp::Void' followed by 'void' is illegal (did you forget a ';'?)
thirdparty\capnproto\include\capnp\common.h(64): error C2513: 'capnp::Void': no variable declared before '='
thirdparty\capnproto\include\capnp\common.h(96): error C2062: type 'void' unexpected
thirdparty\capnproto\include\capnp\common.h(106): error C2143: syntax error: missing ';' before '}'
thirdparty\capnproto\include\capnp\common.h(130): error C2065: 'Void': undeclared identifier
thirdparty\capnproto\include\capnp\common.h(130): error C2923: '_::Kind_': 'Void' is not a valid template type argument for parameter 'T'
thirdparty\capnproto\include\capnp\common.h(130): error C2913: explicit specialization; '_::Kind_' is not a specialization of a class template
thirdparty\capnproto\include\capnp\common.h(131): error C2913: explicit specialization; '_::Kind_' is not a specialization of a class template

I can include these  headers in an "empty project" and compile these classes fine so I'm not sure what the deal is.

Kenton Varda

unread,
May 12, 2017, 9:22:44 PM5/12/17
to raypend...@gmail.com, capnproto
Hi,

The problem is that windows.h #defines the symbol VOID. You will either need to include windows.h after capnp headers, or you will need to #undef VOID after the include.

We should probably make this more automatic, or at least provide a better error message...

-Kenton

--
You received this message because you are subscribed to the Google Groups "Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email to capnproto+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/capnproto.

raypend...@gmail.com

unread,
May 15, 2017, 9:52:55 AM5/15/17
to Cap'n Proto
Thank you for setting me on the right track. That was it. Actually there were a couple of similar issues but they were all related to stuff being already defined before kj and capnp. Here (for posterity) is what I had to do:

In my PCH for the Unreal project:

// Changes to allow Cap'n Proto headers to compile
//Include\kj/debug.h(505): error C4800: 'int': forcing value to bool 'true' or 'false' (performance warning)
#pragma warning(disable:4800)
#include <kj/windows-sanity.h>

also, in classes that used the message types I had to (as you said) #undef VOID and also with the example schema #undef MOBILE in one class. I have a Python client that's sending messages to Actors in the game (each on their own port)... so success. 

Thanks again.

Harris Hancock

unread,
May 15, 2017, 9:01:34 PM5/15/17
to Kenton Varda, raypend...@gmail.com, capnproto
Kenton,

I have a suggestion for a solution over on the GitHub issue for this: https://github.com/sandstorm-io/capnproto/issues/284

It involves `#include`ing a preamble and postamble header at the start and end of every public header -- the preamble uses `#pragma push_macro` on problematic defines and the postamble restores them with `#pragma pop_macro`. I stole the idea from Boost.Asio. I know it's gross, but it seems like the most robust solution to me, and allows us to emulate `system_header` behavior. I can submit a PR implementing this idea for consideration in a week or two.

Harris

Kenton Varda

unread,
May 16, 2017, 1:20:29 PM5/16/17
to Harris Hancock, Kenton Varda, raypend...@gmail.com, capnproto
Another possible solution is to convert macros into proper symbols in the global scope. E.g.

#ifdef VOID
typedef VOID VOID_;
#undef VOID
typedef VOID_ VOID;
#endif

This approach then allows the application to use both the Windows VOID symbol and capnp::VOID without doing its own macro tricks.

That said, the ability to emulate system_header for MSVC would be nice.

-Kenton

Harris Hancock

unread,
May 16, 2017, 2:36:26 PM5/16/17
to Kenton Varda, Kenton Varda, Raymond Pendergraph, capnproto
On Tue, May 16, 2017 at 10:19 AM, Kenton Varda <ken...@cloudflare.com> wrote:
Another possible solution is to convert macros into proper symbols in the global scope. E.g.

#ifdef VOID
typedef VOID VOID_;
#undef VOID
typedef VOID_ VOID;
#endif

This approach then allows the application to use both the Windows VOID symbol and capnp::VOID without doing its own macro tricks.

Hmm, that would be a nice advantage. It would also be implementable by just including a (slightly modified/enhanced) kj/windows-sanity.h in kj/common.h or whatever header is guaranteed to be included by any and all capnp headers.

I'm not sure which approach I prefer, now. I'll think about it and revisit it next week when I can hack on it. :)

Michi Henning

unread,
May 16, 2017, 7:35:59 PM5/16/17
to Harris Hancock, capnproto
A better option might be to dismember whoever wrote that macro in the first place…

Michi.


To unsubscribe from this group and stop receiving emails from it, send an email to capnproto+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages