c++ - Returning Image Pointer to Erlang -


i trying use opencv erlang nif. want basic thing , that's read picture , send pointer erlang. , able again send pointer received c , show pic

so niftest.cpp this:

/* niftest.cpp */  #include "erl_nif.h" #include <opencv/highgui.h> #include <opencv/cv.h> using namespace cv; using namespace std;   static erlnifresourcetype* frame_res = null;   typedef struct _frame_t { iplimage* _frame; } frame_t;  //------------------------------------------------------------------------------ // nif callbacks //------------------------------------------------------------------------------  static void frame_cleanup(erlnifenv* env, void* arg) { enif_free(arg); }  static int load(erlnifenv* env, void** priv, erl_nif_term load_info) {  erlnifresourceflags flags = (erlnifresourceflags) (erl_nif_rt_create | erl_nif_rt_takeover); frame_res = enif_open_resource_type(env, "niftest", "ocv_frame",                       &frame_cleanup,                       flags, 0); return 0; }   static erl_nif_term get_pic(erlnifenv* env, int argc, const erl_nif_term argv[]) {  iplimage* src = cvloadimage("/home/khashayar/downloads/pic.png");  cout << src->width << endl;  iplimage* gray = cvcreateimage(cvgetsize(src), ipl_depth_8u, 1); cvcvtcolor(src, gray, cv_rgb2gray);  frame_t* frame = (frame_t*)enif_alloc_resource(frame_res, sizeof(frame_t)); frame->_frame = gray ;  erl_nif_term term = enif_make_resource(env, frame); enif_release_resource(frame); return enif_make_tuple2(env, enif_make_atom(env, "ok"), term);   }   static erl_nif_term show_pic(erlnifenv* env, int argc, const erl_nif_term argv[]){  frame_t* frame;  if (!enif_get_resource(env, argv[0], frame_res, (void**) &frame)) {    return enif_make_badarg(env);  }   cvshowimage("yoohoo", frame->_frame);   cvwaitkey(30);   return enif_make_atom(env, "ok"); }  static erlniffunc nif_funcs[] =   {     {"show_pic", 1, show_pic},     {"get_pic", 0, get_pic}   };  erl_nif_init(niftest,nif_funcs,load,null,null,null) 

and niftest.erl looks :

-module(niftest).  -compile(export_all).  init() ->       erlang:load_nif("./niftest", 0).  get_pic() ->       "nif library not loaded".  show_pic(f) ->       "nif library not loaded". 

so problem when call get_pic in return {ok, <<>>} , pointer not valid @ all.

when cout frame before making enif_make_resource has value , can see returns empty me!

what doing wrong? have read documentation , can't figure out.

note: can compile code command:

g++ -fpic -shared -o niftest.so niftest.cpp -lopencv_core -lopencv_imgproc -lopencv_highgui -i /usr/lib64/erlang/usr/include/ 

and run erlang shell , call init , get_pic function

nif wrong solution port opencv's high-level gui.

yet, answer question: apparently empty binary in {ok, <<>>} tuple opaque erlang. resource object documented in erl_nif manual page.

resource objects garbage collector friendly. if no process refers given resource, cleanup function called. typically proper structure embedding c or c++ pointers in nif.

iplimage* pointer perfect candidate resource object. not need frame_t type can cast pointer iplimage**. cleanup function should release memory and, in example, call cvreleaseimage.

since pointer opaque, need port accessor functions provide data erlang. depends on kind of data extract image. example, port cvencodeimage function , convert data cvmat* erlang binary using enif_make_binary.

also, side note, instead of returning list "nif library not loaded", should call erlang:nif_error/1,2 in stub functions.

the proper approach port api such opencv's high gui external driver (or c-node).

there several reasons, including:

  • nif calls should return (calling cvwaitkey poor candidate nif, computations taking long), otherwise confuse scheduler ;
  • with nif or linked-in driver, memory management directly impacts erlang's virtual machine, , crash take whole erlang node down.

an external driver process gets data stdin (typically) , replies on stdout. simple design in c or c++. either port opencv's api or more complex functions depending on needs. in case, pointers such iplimage* transferred opaque series of 4 or 8 bytes, or reference number provided maintain list of iplimage* pointers erlang has allocated. unlike nifs, however, there no resource object , have design erlang-side code ensure memory released.

you find more information , sample code in interoperability tutorial user's guide.

see question: opencv on erlang


Comments

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

java - Copying object fields -

c++ - Clear the memory after returning a vector in a function -