Oct. 9th, 2009

DBus

Oct. 9th, 2009 11:57 am
madf: (Default)
Тут, нещодавно, [livejournal.com profile] aceler писав про DBus, qdbus і всяке таке...
Я вирішив викласти свій скрипт now-playing для irssi. На Perl я ніколи нічого не писав, не сильно сваріть :)
use Irssi;
use Net::DBus;
use strict;

use vars qw($VERSION %IRSSI);

$VERSION = "2.00";
%IRSSI = (

    authors     => 'madf',
    name        => 'Amarok status',
    description => 'Shows now playing',
    license     => 'Public Domain'
);

my $bus = Net::DBus->session;

my $amarok = $bus->get_service('org.kde.amarok');
my $object = $amarok->get_object('/Player',
                                 'org.freedesktop.MediaPlayer');


sub cmd_song {
    my ($data, $server, $channel) = @_;
    my $title;

    if (!$server || !$server->{connected}) {

        Irssi::print("Not connected to server");
        return;
    }

    my $metadata = $object->GetMetadata();

    my $artist = $$metadata{"artist"};
    my $title = $$metadata{"title"};
    my $bitrate = $$metadata{"audio-bitrate"};
    
    my $out = 'np(AmK): \'' . $artist . ' - ' . $title . '\' with ' . $bitrate . ' kbps';
    
    if ($channel && ($channel->{type} eq "CHANNEL" || $channel->{type} eq "QUERY")) {

        $channel->command("MSG " . $channel->{name} . " " . $out);
    } else {

    }
    
}

Irssi::command_bind('amarok', 'cmd_song');




syntax highlighted by Code2HTML, v. 0.9.1

Угу

Oct. 9th, 2009 01:47 pm
madf: (Default)
$ links2 -g

"Video options"

vtable

Oct. 9th, 2009 09:57 pm
madf: (Default)
Була тільки що невеличка дискусія з Борисом з приводу застосування memcpy для ініціалізації членів класу у об'єкті. Всі пишуть про те що memcpy неможна використовувати для non-POD типів даних. А non-POD нам дає, як мінімум, наявність деструктора чи оператора operator=.
Дискусія затягнулась, тому довелось застосувати зброю масового знищення - прямий експеримент.
Джерельні коди:
#include <cstdlib>
#include <iostream>

using namespace std;

class B1 {
    public:
        int a;
        int b;
        int x;

        virtual void y();
};

void B1::y()
{
    a = b;
}

class B2 {
    public:
        int c;
        int d;
};

class D : public B1, public B2 {
};

int main (int argc, char** argv){
    D dd;
    B1 * b1;
    B2 * b2;

    dd.a = 0;
    dd.b = 1;
    dd.c = 2;
    dd.d = 3;

    b1 = &dd;
    b2 = &dd;

    int a, b, c, d, x;

    a = b1->a;
    b = b1->b;
    c = b2->c;
    d = b2->d;
    x = b1->x;

    cout << a << ", " << b << ", " << c << ", " << d << ", " << x << endl;

    return EXIT_SUCCESS;
}
_Winnie C++ Colorizer

gdb (перед виводом на консоль):
(gdb) print &dd
$1 = (D *) 0xbfbd5e40
(gdb) print b1
$2 = (D *) 0xbfbd5e40
(gdb) print b2
$3 = (B2 *) 0xbfbd5e50

Тут для мене повна несподіванка - вказівник один а адреси різні!
(gdb) print &b1->a
$4 = (int *) 0xbfbd5e44

Ага! Таблиця віртуальних методів за зміщенням 0 у кількості 1 елемент!
(gdb) print &b2->c
$5 = (int *) 0xbfbd5e50

У B2 віртуальних методів немає, тому таблиці теж немає і адреса c співпадає з адресою B2.

Таким чином, memcpy таки можна використовувати... доки у вас немає віртуальних методів. Щодо оператора operator= я не перевіряв, а от деструктор перевірив.
Якщо деструктор не віртуальний - ніяких проблем. Але при наявному наслідуванні деструктор рекомендують робити віртуальним (Я думаю, всім зрозуміло чому). Таким чином виникає віртуальний метод, vtable і неможливість використовувати memcpy.

Profile

madf: (Default)
madf

April 2018

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
2930     

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 30th, 2025 11:13 am
Powered by Dreamwidth Studios