goertzenator / nifpp Goto Github PK
View Code? Open in Web Editor NEWC++11 Wrapper for Erlang NIF API
C++11 Wrapper for Erlang NIF API
Not exactly sure what's going on here as my C++ template-fu is not strong, but:
erlang 19.0
Darwin spatula 15.4.0 Darwin Kernel Version 15.4.0: Fri Feb 26 22:08:05 PST 2016; root:xnu-3248.40.184~3/RELEASE_X86_64 x86_64
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ make
c++ -g -O3 -ansi -pedantic -Wall -Wextra -I../ -I/usr/local/lib/erlang/erts-8.0/include -fPIC -std=c++11 -c nifpptest.cpp
nifpptest.cpp:419:40: warning: unused parameter 'priv' [-Wunused-parameter]
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
^
nifpptest.cpp:419:59: warning: unused parameter 'load_info' [-Wunused-parameter]
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
^
nifpptest.cpp:427:52: warning: unused parameter 'argc' [-Wunused-parameter]
static ERL_NIF_TERM invoke_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
^
nifpptest.cpp:439:49: warning: unused parameter 'argc' [-Wunused-parameter]
static ERL_NIF_TERM foo_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
^
nifpptest.cpp:449:49: warning: unused parameter 'argc' [-Wunused-parameter]
static ERL_NIF_TERM bar_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
^
nifpptest.cpp:460:33: warning: missing field 'flags' initializer [-Wmissing-field-initializers]
{"invoke_nif", 1, invoke_nif},
^
In file included from nifpptest.cpp:1:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iostream:38:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/ios:216:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__locale:18:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/mutex:177:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:659:21: error: invalid operands to binary expression
('const nifpp::TERM' and 'const nifpp::TERM')
{return __x == __y;}
~~~ ^ ~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:1759:21: note: in instantiation of member function
'std::__1::equal_tonifpp::TERM::operator()' requested here
if (key_eq()(__nd->_value, __x))
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:1724:12: note: in instantiation of function
template specialization 'std::__1::__hash_table<nifpp::TERM, std::__1::hashnifpp::TERM, std::__1::equal_tonifpp::TERM, std::__1::allocatornifpp::TERM
>::__insert_unique_value<const nifpp::TERM &>' requested here
return __insert_unique_value(__x);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_set:495:26: note: in instantiation of member function
'std::__1::__hash_table<nifpp::TERM, std::__1::hashnifpp::TERM, std::__1::equal_tonifpp::TERM, std::__1::allocatornifpp::TERM >::__insert_unique' requested
here
{return _table.__insert_unique(__x);}
^
../nifpp.h:991:59: note: in instantiation of member function 'std::__1::unordered_set<nifpp::TERM, std::__1::hashnifpp::TERM, std::__1::equal_tonifpp::TERM,
std::__1::allocatornifpp::TERM >::insert' requested here
return list_for_each(env, term, [&var](T item){var.insert(item);});
^
../nifpp.h:1104:9: note: in instantiation of function template specialization 'nifpp::getnifpp::TERM' requested here
if(!get(env, term, t))
^
nifpptest.cpp:40:5: note: in instantiation of function template specialization 'nifpp::get_throws<std::__1::unordered_set<nifpp::TERM, std::__1::hashnifpp::TERM,
std::__1::equal_tonifpp::TERM, std::__1::allocatornifpp::TERM > >' requested here
get_throws(env, term, container);
^
nifpptest.cpp:282:39: note: in instantiation of function template specialization 'set2_test<std::__1::unordered_set<nifpp::TERM, std::__1::hashnifpp::TERM,
std::__1::equal_tonifpp::TERM, std::__1::allocatornifpp::TERM > >' requested here
else if(cmd=="list2bf") { return set2_teststd::unordered_set<nifpp::TERM >(env, cmddata); }
^
In file included from nifpptest.cpp:11:
In file included from ../nifpp.h:42:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_set:323:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:1993:32: error: no matching function for call to
object of type 'key_equal' (aka 'std::__1::__unordered_map_equal<nifpp::TERM, std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>,
std::__1::equal_tonifpp::TERM, true>')
key_eq()(__cp->_value, __np->_next->_value);
^~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:1939:9: note: in instantiation of member function
'std::__1::__hash_table<std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>, std::__1::__unordered_map_hasher<nifpp::TERM,
std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>, std::__1::hashnifpp::TERM, true>, std::__1::__unordered_map_equal<nifpp::TERM,
std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>, std::__1::equal_tonifpp::TERM, true>, std::__1::allocator<std::__1::__hash_value_type<nifpp::TERM,
nifpp::TERM> > >::__rehash' requested here
__rehash(__n);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:1587:13: note: in instantiation of member function
'std::__1::__hash_table<std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>, std::__1::__unordered_map_hasher<nifpp::TERM,
std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>, std::__1::hashnifpp::TERM, true>, std::__1::__unordered_map_equal<nifpp::TERM,
std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>, std::__1::equal_tonifpp::TERM, true>, std::__1::allocator<std::__1::__hash_value_type<nifpp::TERM,
nifpp::TERM> > >::rehash' requested here
rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_map:1536:41: note: in instantiation of member function
'std::__1::__hash_table<std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>, std::__1::__unordered_map_hasher<nifpp::TERM,
std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>, std::__1::hashnifpp::TERM, true>, std::__1::__unordered_map_equal<nifpp::TERM,
std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>, std::__1::equal_tonifpp::TERM, true>, std::__1::allocator<std::__1::__hash_value_type<nifpp::TERM,
nifpp::TERM> > >::__node_insert_unique' requested here
pair<iterator, bool> __r = _table.__node_insert_unique(__h.get());
^
nifpptest.cpp:76:9: note: in instantiation of member function 'std::__1::unordered_map<nifpp::TERM, nifpp::TERM, std::__1::hashnifpp::TERM,
std::__1::equal_tonifpp::TERM, std::__1::allocator<std::__1::pair<const nifpp::TERM, nifpp::TERM> > >::operator[]' requested here
outmap[i->second] = i->first;
^
nifpptest.cpp:310:40: note: in instantiation of function template specialization 'umapflip_test<nifpp::TERM, nifpp::TERM>' requested here
else if(cmd=="mapflipab") { return umapflip_test<nifpp::TERM, nifpp::TERM>(env, cmddata); }
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_map:476:10: note: candidate function not viable: no
known conversion from 'value_type' (aka 'std::__1::__hash_value_type<nifpp::TERM, nifpp::TERM>') to 'const nifpp::TERM' for 1st argument
bool operator()(const _Key& __x, const _Cp& __y) const
^
6 warnings and 2 errors generated.
make: *** [nifpptest.o] Error 1
How would you write a resource constructor for https://bkaradzic.github.io/bgfx/bgfx.html#_CPPv2N4bgfx4initEN12RendererType4EnumE8uint16_t8uint16_tP9CallbackIPN2bx12ReallocatorIE
bool bgfx::init(RendererType::Enum _type, uint16_t _vendorId, uint16_t _deviceId, CallbackI *_callback, bx::ReallocatorI *_reallocator).
Where https://bkaradzic.github.io/bgfx/bgfx.html#_CPPv2N4bgfx9CallbackIE is an abstract class?
Currently it breaks on being impossible to instanstiate abstract classes.
struct CallbackI
{
virtual ~CallbackI() = 0;
virtual void fatal(Fatal::Enum _code, const char* _str) = 0;
virtual void traceVargs(const char* _filePath, uint16_t _line, const char* _format, va_list _argList) = 0;
virtual uint32_t cacheReadSize(uint64_t _id) = 0;
virtual bool cacheRead(uint64_t _id, void* _data, uint32_t _size) = 0;
virtual void cacheWrite(uint64_t _id, const void* _data, uint32_t _size) = 0;
virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t _size, bool _yflip) = 0;
virtual void captureBegin(uint32_t _width, uint32_t _height, uint32_t _pitch, TextureFormat::Enum _format, bool _yflip) = 0;
virtual void captureEnd() = 0;
virtual void captureFrame(const void* _data, uint32_t _size) = 0;
};
Here is what I have:
#ifdef __GNUC__
#define UNUSED(x) UNUSED_##x __attribute__((__unused__))
#else
#define UNUSED(x) UNUSED_##x
#endif
#include "nifpp.h"
#include <stdio.h>
#ifndef _WIN32
#include <strings.h>
#include <unistd.h>
#else
#endif
//#include "bx/platform.h"
#include "bgfx/bgfx.h"
using namespace nifpp;
extern "C" {
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
{
nifpp::register_resource<bgfx::RendererType::Enum>(env, nullptr, "renderer_type");
nifpp::register_resource<bgfx::CallbackI>(env, nullptr, "callback_interface");
nifpp::register_resource<bx::ReallocatorI>(env, nullptr, "reallocator_interface");
return 0;
}
static ERL_NIF_TERM _hello(ErlNifEnv *env, int UNUSED(arc),
const ERL_NIF_TERM UNUSED(argv[])) {
return make(env, 0.0);
}
static ERL_NIF_TERM ex_bgfx_init(ErlNifEnv *env, int argc,
const ERL_NIF_TERM argv[]) {
try {
auto _type = nifpp::construct_resource<bgfx::RendererType::Enum>(nifpp::get<bgfx::RendererType::Enum>(env, argv[0]));
auto _vendor_id = nifpp::get<uint16_t>(env, argv[1]);
auto _device_id = nifpp::get<uint16_t>(env, argv[2]);
//bgfx_callback_interface_t* _callback;
//bgfx_reallocator_interface_t* _reallocator;
//nifpp::get<std::string>(env, argv[3], nifpp::get<std::string>(env, argv[0]));
//nifpp::get<std::string>(env, argv[4], _reallocator);
auto _callback = nifpp::construct_resource<bgfx::CallbackI>(nifpp::get<bgfx::CallbackI *>(env, argv[3]));
auto _reallocator = nifpp::construct_resource<bx::ReallocatorI>(nifpp::get<bx::ReallocatorI *>(env, argv[4]));
return make(env, bgfx::init(*_type, _vendor_id, _device_id, &*_callback,
&*_reallocator));
} catch (nifpp::badarg) {
}
return enif_make_badarg(env);
}
static ErlNifFunc nif_funcs[] = {
{"_hello", 0, _hello, 0}, {"bgfx_init", 0, _hello, 0},
};
ERL_NIF_INIT(Elixir.ExBgfx.Nif, nif_funcs, NULL, NULL, NULL, NULL)
} // extern C
Proplists are complex. Currently
std::vector<nifpp::binary> mylist
gives an error.
There should be some way to create and manipulate it.
Is it possible to have a construct_resource that lasts until manually destroyed?
Review const
ness of the container make()
functions because the underlying make functions (ie enif_make_binary
) are non-const. I recently had problems trying to make()
a std::array<ErlNifBinary, N>
.
when using nifpp like this
std::string s {"something"};
nifpp::TERM a = nifpp::make(env,s);
return a;
upon calling function i get:
{load_failed,"Failed to load NIF library: './priv/substitutor.so: undefined symbol: __gxx_personality_v0'"}
i'm on ubuntu 16.04, and i'm compiling with g++
Trying to enable dirty schedule but I don't see an option.
https://medium.com/@jlouis666/erlang-dirty-scheduler-overhead-6e1219dcc7#.kj4ehn1wm
nifpp::get should accept an rvalue tuple consisting of lvalue references. Currently only lvalue tuples are accepted.
We want the following to work:
int a,b;
nifpp::get_throws(env, term, std::tie(a,b)); // crack {123, 456}
Thanks for you the nifpp project. Quite useful one.
I have a quick question on representing maps of maps. For example if I would like to return this following map to the Erlang from a nif, how could I do that?
#{
abc => 1,
mln => "mln",
pqr => #{
a => 1,
b => 2
}
}
Thanks
-Vasu
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.