<div dir="ltr">Regarding C++ types in extern "C":  That is a very good question...<div><br></div><div>I looked into the C++ standard and other documents.  The answer is that extern "C"  just changes the default linkage to "C" instead of "C++".  Everything else remains the same, so you can still use the rest of C++ inside an extern "C", but the linkage may impose some limitations (like no function overloading).  "C" linkage names only indicate the name the of the function but not the parameter or return types like C++ linkage names.</div>
<div><br></div><div>Now that I am a little more educated on linking and calling conventions, I am uncomfortable with the patches I have suggested.  Sure, they work on linux with gcc, but will they work on MSVC?  What about the other less common unices?  I think depending on linker looseness is brittle.</div>
<div><br></div><div>As an alternate idea, I think I can generate inline C++ wrappers for the whole NIF API and get a unique ERL_NIF_TERM type that way.  It's not very elegant, but everything gets resolved at compile time with no linker tricks, and the compiler should flatten the wrapper away so that there is no overhead.</div>
<div><br></div><div>So, if you agree, I'd like to take this patch out back and shoot it. :)</div><div><br></div><div>Dan.</div><div><br></div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Mon, Feb 10, 2014 at 7:09 AM, Sverker Eriksson <span dir="ltr"><<a href="mailto:sverker.eriksson@ericsson.com" target="_blank">sverker.eriksson@ericsson.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The "hook" solution has an advantage I think. It leaves it up to the user to define the type and thereby to "make it work".<br>

<br>
I actually don't understand how you get this to work. How can you mix C++ types within a extern "C" declaration?<br>
<br>
/Sverker<div><div class="h5"><br>
<br>
On 02/07/2014 08:21 PM, Daniel Goertzen wrote:<br>
</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
Thank you for your feedback.  Maybe the "hook" approach I suggested is too<br>
generic.  My original patch from nifpp actually looks like this...<br>
<br>
#ifdef CPP11_UNIQUE_TERM_TYPE<br>
   enum class ERL_NIF_TERM : ERL_NIF_UINT;<br>
#else<br>
   typedef ERL_NIF_UINT ERL_NIF_TERM;<br>
#endif<br>
<br>
...and then to use the typed enum in your c++ nif you write...<br>
<br>
#define CPP11_UNIQUE_TERM_TYPE<br>
#include <erl_nif.h><br>
<br>
<br>
In the future ERL_NIF_TERM can be changed to a struct and the<br>
CPP11_UNIQUE_TERM_TYPE option can just be ignored.  What do you think?<br>
<br>
Cheers,<br>
Dan.<br>
<br>
<br>
On Fri, Feb 7, 2014 at 12:46 PM, Sverker Eriksson <<br>
<a href="mailto:sverker.eriksson@ericsson.com" target="_blank">sverker.eriksson@ericsson.com</a>> wrote:<br>
<br>
</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
  Thanks for the patch.<br>
<br>
I got one objection/question though. My C++ knowledge is a bit rusty but<br>
as I understand it<br>
the "enum class" construct demands that Type is an integer type.<br>
<br>
This is currently true for ERL_NIF_TERM but it might not be in the future.<br>
I earlier tried to define ERL_NIF_TERM as<br>
<br>
typedef struct { int x; } ERL_NIF_TERM;<br>
<br>
to get stronger type checking even for C. I reverted that due to bad<br>
performance<br>
as gcc has different calling conventions for int and struct {int}.<br>
However, future compilers<br>
might be better at passing struct{int} by value in which case we might<br>
want to change<br>
the definition of ERL_NIF_TERM.<br>
<br>
What then? Do we ignore CUSTOM_NIF_TERM_TYPE in such a scenario?<br>
<br>
<br>
/Sverker, Erlang/OTP<br>
<br>
<br>
<br>
On 02/07/2014 06:34 PM, Daniel Goertzen wrote:<br>
<br>
When writing NIFs in C++, it is impossible to employ C++ function<br>
overloading because the underlying type of ERL_NIF_TERM is "unsigned int".<br>
For example:<br>
<br>
// won't compile :(<br>
#include <erl_nif.h><br>
void my_func(ERL_NIF_TERM a)  {...}<br>
void my_func(unsigned int a)  {...}<br>
<br>
<br>
This patch allows NIF authors to mutate the type of ERL_NIF_TERM by<br>
defining the macro CUSTOM_NIF_TERM_TYPE().  In the example below, the<br>
underlying unsigned integer type gets wrapped as a C++11 typed<br>
enumeration.  The type of ERL_NIF_TERM is now unique and can be used in<br>
overloaded functions.<br>
<br>
// compiles!  :)<br>
#define CUSTOM_NIF_TERM_TYPE(Type) enum class ERL_NIF_TERM : Type {};<br>
#include <erl_nif.h><br>
void my_func(ERL_NIF_TERM a)  {...}<br>
void my_func(unsigned int a)  {...}<br>
<br>
<br>
The patch has no impact on erl_nif.h if CUSTOM_NIF_TERM_TYPE is not defined<br>
(other than flipping the definition order of ERL_NIF_TERM and ERL_NIF_UINT).<br>
<br></div></div>
A similar approach has been used on my C++11 NIF wrapper (<a href="https://github.com/goertzenator/nifpp" target="_blank">https://github.com/<u></u>goertzenator/nifpp</a>).  The wrapper requires manual<div class=""><br>
installation of a similar patch, and I would love to remove that<br>
requirement.<br>
<br>
Regards,<br>
Dan.<br>
<br>
<br>
<br>
<br>
______________________________<u></u>_________________<br>
erlang-patches mailing listerlang-patches@erlang.<u></u>orghttp://<a href="http://erlang.org/mailman/listinfo/erlang-patches" target="_blank">erlang.org/mailman/<u></u>listinfo/erlang-patches</a><br>
<br>
<br>
<br>
</div></blockquote></blockquote>
<br>
</blockquote></div><br></div>