Help - Search - Members - Calendar
Full Version: help with play_callback
Hydrogenaudio Forums > Hosted Forums > foobar2000 > Development - (fb2k)
cookir
I'm a complete C++ noob, so there's probably a simple explanation that I'm completely blind to.

I'm making this for a friend, all he wants is on a new track, get a cgi script on a webserver with the title/artist. I haven't passed the variables yet, but the connection works fine.

This compiles fine, and when a new song is played, it works, but if you try to do ANYTHING after that, like minimise, open console, stop, next track.. it crashes... twice...

Please could someone have a look for me, it's very frustrating, but then I've only been using C++ for 2 days...

Here's the code:
CODE
#include "../SDK/foobar2000.h"
#include "../SDK/play_callback.h"
#include "resource.h"
#include "../foo_read_http/jnetlib/jnetlib.h"

static cfg_int cfg_enable_urlpost("enable_urlpost",0);

class play_callback_urlpost : public play_callback
{
virtual void on_playback_starting(){};
virtual void on_playback_stop(play_control::stop_reason reason){};
virtual void on_playback_seek(double time){};
virtual void on_playback_pause(int state){};
virtual void on_playback_edited(metadb_handle * track){};
virtual void on_playback_dynamic_info(const file_info * info,bool b_track_change){};
virtual void on_volume_change(int new_val) {};


virtual void on_playback_new_track(metadb_handle * track)
{
 if(cfg_enable_urlpost) {
  metadb_handle * myhandle = track;
  const file_info * myinfo;
  myhandle->handle_lock();
  myinfo = myhandle->handle_query_locked();
 
  if(myinfo) {
   // stuff
   //string8 name = myinfo->meta_enum_name(0);
   //string8 value = myinfo->meta_enum_value(0);
   
   JNL::open_socketlib();
   JNL_HTTPGet *thingy=new JNL_HTTPGet(JNL_CONNECTION_AUTODNS,16384,NULL);
   
   thingy->addheader("User-Agent: COOOOKKKIIIEEEEE (Mozilla)");*/
   thingy->addheader("Accept: */*");
   thingy->connect("http://biguglycow.co.uk/cgi-bin/llama.php");
   bool quit = 0;  
   while(!quit) {
    int st = thingy->run ();

    if (st == -1) {
    break;
   } else if (st == 1) {
    break;
   } else {
   
    if(thingy->get_status() == 0) {
     Sleep(25);
    }
    else if(thingy->get_status() == 1) {
     Sleep(25);
    }
    else if(thingy->get_status() == 2) {
     quit = 1;
     break;
    }
   }
   }
   
 
   thingy->~JNL_HTTPGet();
   JNL::close_socketlib();
  }
  delete myinfo;
  myhandle->handle_unlock();
  myhandle->handle_release();
 }
 return;
}
};

class config_urlpost : public config
{
static BOOL CALLBACK ConfigProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
{
 switch(msg)
 {
 case WM_INITDIALOG:
  uSendDlgItemMessage(wnd,IDC_ENABLE_URLPOST,BM_SETCHECK,cfg_enable_urlpost,0);
  break;
 case WM_COMMAND:
  switch(wp)
  {
  case IDC_ENABLE_URLPOST:
   cfg_enable_urlpost = uSendMessage((HWND)lp,BM_GETCHECK,0,0);
   break;
  }
  break;
 }
 return 0;
}
public:
virtual HWND create(HWND parent)
{
 return uCreateDialog(IDD_CONFIG,parent,ConfigProc);
}
virtual const char * get_name() {return "URL Poster";}
virtual const char * get_parent_name() {return "Components";}
};

static play_callback_factory<play_callback_urlpost> foo;
static config_factory<config_urlpost> foo2;
//DECLARE_COMPONENT_VERSION("URL Poster (gg next map plz)","0.1","Posts to a url.\nby cookie from hacked up focus plugin");


and here's some crash log
CODE
Illegal operation:
Code: C0000005h, flags: 00000000h, address: 00410FD8h
Access violation, operation: read, address: 000005BEh
Call path:
WinMain=>app_mainloop=>play_callback::on_playback_time=>playback_format_title_ex=>play_callback::on_playback_time=>playback_format_title_ex=>menu command: "Components/Show console"=>playback_format_title_ex
This is the first crash logged by this instance.


blink.gif crying.gif
foosion
Change the line
CODE
thingy->~JNL_HTTPGet();

to
CODE
delete thingy;

and delete
CODE
delete myinfo;


Explanation:
You don't call desctructors directly, the delete operator does that automatically. You must not delete the file_info pointed to by myinfo, as that object is owned by the metadb_handle in track.

Additionally, doing a HTTP request from inside playback_callback::on_playback_new_track()isn't a good idea, as it may lock fb2k until the request is finished...
cookir
ah yes i see, thank you.

so would the best method to be to create a new thread and run the request in there?
foosion
Yes, but remember to call handle_add_ref() on the handle passed in the callback (another mistake I just spotted in your code - that handle_release() you do is illegal since you didn't call handle_add_ref() before). Remember to use thread synchronization where appropriate.
cookir
ahh that's why it crashed on exit ehehe

many thanks, and my apologies for being a complete newbie. i'll attempt the thread stuff, and then come back when i've messed that up too

smile.gif
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2008 Invision Power Services, Inc.