<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" ><channel><title>LINUX For You &#187; Coding</title> <atom:link href="http://www.linuxforu.com/category/teach-me/coding/feed/" rel="self" type="application/rss+xml" /><link>http://www.linuxforu.com</link> <description>The Complete Magazine on Open Source</description> <lastBuildDate>Tue, 31 Jan 2012 17:22:40 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=</generator> <xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /> <item><title>Device Drivers, Part 14: A Dive Inside the Hard Disk for Understanding Partitions</title><link>http://www.linuxforu.com/2012/01/device-drivers-partitions-hard-disk/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=device-drivers-partitions-hard-disk</link> <comments>http://www.linuxforu.com/2012/01/device-drivers-partitions-hard-disk/#comments</comments> <pubDate>Tue, 31 Jan 2012 10:47:17 +0000</pubDate> <dc:creator>Anil Kumar Pugalia</dc:creator> <category><![CDATA[Coding]]></category> <category><![CDATA[Developers]]></category> <category><![CDATA[BIOS]]></category> <category><![CDATA[boot]]></category> <category><![CDATA[device drivers]]></category> <category><![CDATA[DOS]]></category> <category><![CDATA[fdisk]]></category> <category><![CDATA[Hard disk drive]]></category> <category><![CDATA[hard disks]]></category> <category><![CDATA[kernel]]></category> <category><![CDATA[kernel programming]]></category> <category><![CDATA[LFY January 2012]]></category> <category><![CDATA[linked-list head]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[linux device drivers]]></category> <category><![CDATA[Linux Device Drivers Series]]></category> <category><![CDATA[MBR]]></category> <category><![CDATA[mechanical engineering]]></category> <category><![CDATA[Minix]]></category> <category><![CDATA[operating system]]></category> <category><![CDATA[Partition table]]></category> <category><![CDATA[partitions]]></category> <category><![CDATA[platters]]></category> <category><![CDATA[sectors]]></category> <category><![CDATA[storage systems]]></category><guid isPermaLink="false">http://www.linuxforu.com/?p=9439</guid> <description><![CDATA[This article, which is part of the series on Linux device drivers, takes you on a tour inside a hard disk. &#8220;Doesn&#8217;t it sound like a mechanical engineering subject: The design of the...]]></description> <content:encoded><![CDATA[<p><img src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/Hard-drive-opening-image.jpg?d9c344" alt="Inside the hard drive" title="Inside the hard drive" width="350" height="334" class="alignright size-full wp-image-9441" /><div class="introduction">This article, which is part of the <a href="http://www.linuxforu.com/tag/linux-device-drivers-series/">series on Linux device drivers</a>, takes you on a tour inside a hard disk.</div><p>&#8220;Doesn&#8217;t it sound like a mechanical engineering subject: The design of the hard disk?&#8221; questioned Shweta. &#8220;Yes, it does. But understanding it gives us an insight into its programming aspect,&#8221; reasoned Pugs, while waiting for the commencement of the seminar on storage systems.</p><p>The seminar started with a few hard disks in the presenter&#8217;s hand and then a dive into her system, showing the output of <code>fdisk -l</code> (Figure 1).</p><div id="attachment_9440" class="wp-caption aligncenter" style="width: 590px"><a href="http://cdn.linuxforu.com/wp-content/uploads/2012/01/figure_23_fdisk_listing.png?d9c344"><img src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/figure_23_fdisk_listing-590x448.png?d9c344" alt="Partition listing by fdisk" title="Partition listing by fdisk" width="590" height="448" class="size-large wp-image-9440" /></a><p class="wp-caption-text">Figure 1: Partition listing by fdisk</p></div><p>The first line shows the hard disk size in human-friendly format and in bytes. The second line mentions the number of logical heads, logical sectors per track, and the actual number of cylinders on the disk &#8212; together known as the geometry of the disk.</p><p>The 255 heads indicate the number of platters or disks, as one read-write head is needed per disk. Let&#8217;s number them, say D1, D2,  D255. Now, each disk would have the same number of concentric circular tracks, starting from the outside to the inside. In the above case, there are 60,801 such tracks per disk. Let&#8217;s number them, say T1, T2,  T60801. And a particular track number from all the disks forms a cylinder of the same number. For example, tracks T2 from D1, D2,  D255 will together form the cylinder C2. Now, each track has the same number of logical sectors &#8212; 63 in our case, say S1, S2,  S63. And each sector is typically 512 bytes. Given this data, one can actually compute the total usable hard disk size, using the following formula:</p><pre class="brush: text; gutter: false; first-line: 1">Usable hard disk size in bytes = (Number of heads or disks) * (Number of tracks per disk) * (Number of sectors per track) * (Number of bytes per sector, i.e. sector size)</pre><p>For the disk under consideration, it would be: <code>255 * 60801 * 63 * 512 bytes = 500105249280 bytes</code>.</p><p>Note that this number may be slightly less than the actual hard disk (500107862016 bytes, in our case). The reason is that the formula doesn&#8217;t consider the bytes in the last partial or incomplete cylinder. The primary reason for that is the difference between today&#8217;s technology of organising the actual physical disk geometry and the traditional geometry representation using heads, cylinders and sectors.</p><p>Note that in the <code>fdisk</code> output, we referred to the heads and sectors per track as logical not physical. One may ask that if today&#8217;s disks don&#8217;t have such physical geometry concepts, then why still maintain them and represent them in a logical form? The main reason is to be able to continue with the same concepts of partitioning, and be able to maintain the same partition table formats, especially for the most prevalent DOS-type partition tables, which heavily depend on this simplistic geometry. Note the computation of cylinder size (<code>255 heads * 63 sectors / track * 512 bytes / sector = 8225280 bytes</code>) in the third line and then the demarcation of partitions in units of complete cylinders.</p><h2>DOS-type partition tables</h2><p>This brings us to the next important topic: understanding DOS-type partition tables. But first, what is a partition, and why should we partition? A hard disk can be divided into one or more logical disks, each of which is called a partition. This is useful for organising different types of data separately, for example, different operating system data, user data, temporary data, etc.</p><p>So, partitions are basically logical divisions and need to be maintained by metadata, which is the partition table. A DOS-type partition table contains four partition entries, each a 16-byte entry. Each of these entries can be depicted by the following &#8216;C&#8217; structure:</p><pre class="brush: c; gutter: false; first-line: 1">typedef struct
{
    unsigned char boot_type; // 0x00 - Inactive; 0x80 - Active (Bootable)
    unsigned char start_head;
    unsigned char start_sec:6;
    unsigned char start_cyl_hi:2;
    unsigned char start_cyl;
    unsigned char part_type;
    unsigned char end_head;
    unsigned char end_sec:6;
    unsigned char end_cyl_hi:2;
    unsigned char end_cyl;
    unsigned long abs_start_sec;
    unsigned long sec_in_part;
} PartEntry;</pre><p>This partition table, followed by the two-byte signature <code>0xAA55</code>, resides at the end of the disk&#8217;s first sector, commonly known as the Master Boot Record (MBR). Hence, the starting offset of this partition table within the MBR is <code>512 - (4 * 16 + 2) = 446</code>. Also, a 4-byte disk signature is placed at offset 440.</p><p>The remaining top 440 bytes of the MBR are typically used to place the first piece of boot code, that is loaded by the BIOS to boot the system from the disk. The <code>part_info.c</code> listing contains these various definitions, along with code for parsing and printing a formatted output of the partition table.</p><p>From the partition table entry structure, it could be noted that the start and end cylinder fields are only 10 bits long, thus allowing a maximum of 1023 cylinders only. However, for today&#8217;s huge hard disks, this is in no way sufficient. Hence, in overflow cases, the corresponding <code>&lt;head, cylinder, sector&gt;</code> triplet in the partition table entry is set to the maximum value, and the actual value is computed using the last two fields: the absolute start sector number (abs_start_sec) and the number of sectors in this partition (<code>sec_in_part</code>).</p><p>The code for this too is in <code>part_info.c</code>:</p><pre class="brush: c; gutter: true; first-line: 1">#include &lt;stdio.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;unistd.h&gt;

#define SECTOR_SIZE 512
#define MBR_SIZE SECTOR_SIZE
#define MBR_DISK_SIGNATURE_OFFSET 440
#define MBR_DISK_SIGNATURE_SIZE 4
#define PARTITION_TABLE_OFFSET 446
#define PARTITION_ENTRY_SIZE 16 // sizeof(PartEntry)
#define PARTITION_TABLE_SIZE 64 // sizeof(PartTable)
#define MBR_SIGNATURE_OFFSET 510
#define MBR_SIGNATURE_SIZE 2
#define MBR_SIGNATURE 0xAA55
#define BR_SIZE SECTOR_SIZE
#define BR_SIGNATURE_OFFSET 510
#define BR_SIGNATURE_SIZE 2
#define BR_SIGNATURE 0xAA55

typedef struct {
    unsigned char boot_type; // 0x00 - Inactive; 0x80 - Active (Bootable)
    unsigned char start_head;
    unsigned char start_sec:6;
    unsigned char start_cyl_hi:2;
    unsigned char start_cyl;
    unsigned char part_type;
    unsigned char end_head;
    unsigned char end_sec:6;
    unsigned char end_cyl_hi:2;
    unsigned char end_cyl;
    unsigned long abs_start_sec;
    unsigned long sec_in_part;
} PartEntry;

typedef struct {
    unsigned char boot_code[MBR_DISK_SIGNATURE_OFFSET];
    unsigned long disk_signature;
    unsigned short pad;
    unsigned char pt[PARTITION_TABLE_SIZE];
    unsigned short signature;
} MBR;

void print_computed(unsigned long sector) {
    unsigned long heads, cyls, tracks, sectors;

    sectors = sector % 63 + 1 /* As indexed from 1 */;
    tracks = sector / 63;
    cyls = tracks / 255 + 1 /* As indexed from 1 */;
    heads = tracks % 255;
    printf(&quot;(%3d/%5d/%1d)&quot;, heads, cyls, sectors);
}

int main(int argc, char *argv[]) {
    char *dev_file = &quot;/dev/sda&quot;;
    int fd, i, rd_val;
    MBR m;
    PartEntry *p = (PartEntry *)(m.pt);

    if (argc == 2) {
        dev_file = argv[1];
    }
    if ((fd = open(dev_file, O_RDONLY)) == -1) {
        fprintf(stderr, &quot;Failed opening %s: &quot;, dev_file);
        perror(&quot;&quot;);
        return 1;
    }
    if ((rd_val = read(fd, &amp;m, sizeof(m))) != sizeof(m)) {
        fprintf(stderr, &quot;Failed reading %s: &quot;, dev_file);
        perror(&quot;&quot;);
        close(fd);
        return 2;
    }
    close(fd);
    printf(&quot;\nDOS type Partition Table of %s:\n&quot;, dev_file);
    printf(&quot;  B Start (H/C/S)   End (H/C/S) Type  StartSec    TotSec\n&quot;);
    for (i = 0; i &lt; 4; i++) {
        printf(&quot;%d:%d (%3d/%4d/%2d) (%3d/%4d/%2d)  %02X %10d %9d\n&quot;,
            i + 1, !!(p[i].boot_type &amp; 0x80),
            p[i].start_head,
            1 + ((p[i].start_cyl_hi &lt;&lt; 8) | p[i].start_cyl),
            p[i].start_sec,
            p[i].end_head,
            1 + ((p[i].end_cyl_hi &lt;&lt; 8) | p[i].end_cyl),
            p[i].end_sec,
            p[i].part_type,
            p[i].abs_start_sec, p[i].sec_in_part);
    }
    printf(&quot;\nRe-computed Partition Table of %s:\n&quot;, dev_file);
    printf(&quot;  B Start (H/C/S)   End (H/C/S) Type  StartSec    TotSec\n&quot;);
    for (i = 0; i &lt; 4; i++) {
        printf(&quot;%d:%d &quot;, i + 1, !!(p[i].boot_type &amp; 0x80));
        print_computed(p[i].abs_start_sec);
        printf(&quot; &quot;);
        print_computed(p[i].abs_start_sec + p[i].sec_in_part - 1);
        printf(&quot; %02X %10d %9d\n&quot;, p[i].part_type,
            p[i].abs_start_sec, p[i].sec_in_part);
    }
    printf(&quot;\n&quot;);
    return 0;
}</pre><p>As the above is an application, compile it with <code>gcc part_info.c -o part_info</code>, and then run <code>./part_info /dev/sda</code> to check out your primary partitioning information on <code>/dev/sda</code>. Figure 2 shows the output of <code>./part_info</code> on the presenter&#8217;s system. Compare it with the <code>fdisk</code> output in Figure 1.</p><div id="attachment_9442" class="wp-caption aligncenter" style="width: 590px"><a href="http://cdn.linuxforu.com/wp-content/uploads/2012/01/figure_24_part_info_output.png?d9c344"><img src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/figure_24_part_info_output-590x448.png?d9c344" alt="Output of ./part_info" title="Output of ./part_info" width="590" height="448" class="size-large wp-image-9442" /></a><p class="wp-caption-text">Figure 2: Output of ./part_info</p></div><h2>Partition types and boot records</h2><p>Now, as this partition table is hard-coded to have four entries, that&#8217;s the maximum number of partitions you can have. These are called primary partitions, each having an associated type in the corresponding partition table entry. These types are typically coined by various OS vendors, and hence sort of map to various OSs like DOS, Minix, Linux, Solaris, BSD, FreeBSD, QNX, W95, Novell Netware, etc., to be used for/with the particular OS. However, this is more a formality than a real requirement.</p><p>Besides this, one of the four primary partitions can be labelled as something called an extended partition, which has a special significance. As the name suggests, it is used to further extend hard disk division, i.e., to have more partitions. These are called logical partitions and are created within the extended partition. The metadata of these is maintained in a linked-list format, allowing an unlimited number of logical partitions (at least theoretically).</p><p>For that, the first sector of the extended partition, commonly called the Boot Record (BR), is used like the MBR to store (the linked-list head of) the partition table for the logical partitions. Subsequent linked-list nodes are stored in the first sector of the subsequent logical partitions, referred to as the Logical Boot Record (LBR). Each linked-list node is a complete 4-entry partition table, though only the first two entries are used &#8212; the first for the linked-list data, namely, information about the immediate logical partition, and the second as the linked list&#8217;s next pointer, pointing to the list of remaining logical partitions.</p><p>To compare and understand the primary partitioning details on your system&#8217;s hard disk, follow the steps (as the root user &#8212; hence with care) given below:</p><pre class="brush: text; gutter: false; first-line: 1">./part_info /dev/sda ## Displays the partition table on /dev/sda
fdisk -l /dev/sda ## To display and compare the partition table entries with the above</pre><p>In case you have multiple hard disks (<code>/dev/sdb</code>, &#8230;), hard disk device files with other names (<code>/dev/hda</code>, &#8230;), or an extended partition, you may try <code>./part_info &lt;device_file_name&gt;</code> on them as well. Trying on an extended partition would give you the information about the starting partition table of the logical partitions.</p><p>Right now, we have carefully and selectively played (read-only) with the system&#8217;s hard disk. Why carefully? Since otherwise, we may render our system non-bootable. But no learning is complete without a total exploration. Hence, in our next session, we will create a dummy disk in RAM and do destructive exploration on it.<div id="crp_related"><h5>Related Posts:</h5><ul><li><a href="http://www.linuxforu.com/2012/01/working-with-mtd-devices/" rel="bookmark" class="crp_title">Working with MTD Devices</a></li><li><a href="http://www.linuxforu.com/2012/01/joy-of-programming-understanding-bit-fields-c/" rel="bookmark" class="crp_title">Joy of Programming: Understanding Bit-fields in C</a></li><li><a href="http://www.linuxforu.com/2009/02/improve-multi-os-computer-performance-through-cross-swapping/" rel="bookmark" class="crp_title">Improve Multi-OS Computer Performance through Cross Swapping</a></li><li><a href="http://www.linuxforu.com/2009/03/install-linux-straight-from-an-iso/" rel="bookmark" class="crp_title">Stop Wasting CDs; Install Linux Straight from an ISO</a></li><li><a href="http://www.linuxforu.com/2011/04/getting-started-with-inotify/" rel="bookmark" class="crp_title">Getting Started with Inotify</a></li></ul></div>Tags: <a href="http://www.linuxforu.com/tag/bios/" title="BIOS" rel="tag">BIOS</a>, <a href="http://www.linuxforu.com/tag/boot/" title="boot" rel="tag">boot</a>, <a href="http://www.linuxforu.com/tag/device-drivers/" title="device drivers" rel="tag">device drivers</a>, <a href="http://www.linuxforu.com/tag/dos/" title="DOS" rel="tag">DOS</a>, <a href="http://www.linuxforu.com/tag/fdisk/" title="fdisk" rel="tag">fdisk</a>, <a href="http://www.linuxforu.com/tag/hard-disk-drive/" title="Hard disk drive" rel="tag">Hard disk drive</a>, <a href="http://www.linuxforu.com/tag/hard-disks/" title="hard disks" rel="tag">hard disks</a>, <a href="http://www.linuxforu.com/tag/kernel/" title="kernel" rel="tag">kernel</a>, <a href="http://www.linuxforu.com/tag/kernel-programming/" title="kernel programming" rel="tag">kernel programming</a>, <a href="http://www.linuxforu.com/tag/lfy-january-2012/" title="LFY January 2012" rel="tag">LFY January 2012</a>, <a href="http://www.linuxforu.com/tag/linked-list-head/" title="linked-list head" rel="tag">linked-list head</a>, <a href="http://www.linuxforu.com/tag/linux/" title="Linux" rel="tag">Linux</a>, <a href="http://www.linuxforu.com/tag/linux-device-drivers/" title="linux device drivers" rel="tag">linux device drivers</a>, <a href="http://www.linuxforu.com/tag/linux-device-drivers-series/" title="Linux Device Drivers Series" rel="tag">Linux Device Drivers Series</a>, <a href="http://www.linuxforu.com/tag/mbr/" title="MBR" rel="tag">MBR</a>, <a href="http://www.linuxforu.com/tag/mechanical-engineering/" title="mechanical engineering" rel="tag">mechanical engineering</a>, <a href="http://www.linuxforu.com/tag/minix/" title="Minix" rel="tag">Minix</a>, <a href="http://www.linuxforu.com/tag/operating-system/" title="operating system" rel="tag">operating system</a>, <a href="http://www.linuxforu.com/tag/partition-table/" title="Partition table" rel="tag">Partition table</a>, <a href="http://www.linuxforu.com/tag/partitions/" title="partitions" rel="tag">partitions</a>, <a href="http://www.linuxforu.com/tag/platters/" title="platters" rel="tag">platters</a>, <a href="http://www.linuxforu.com/tag/sectors/" title="sectors" rel="tag">sectors</a>, <a href="http://www.linuxforu.com/tag/storage-systems/" title="storage systems" rel="tag">storage systems</a><br /> ]]></content:encoded> <wfw:commentRss>http://www.linuxforu.com/2012/01/device-drivers-partitions-hard-disk/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Lisp: Tears of Joy, Part 8</title><link>http://www.linuxforu.com/2012/01/lisp-tears-of-joy-part-8/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lisp-tears-of-joy-part-8</link> <comments>http://www.linuxforu.com/2012/01/lisp-tears-of-joy-part-8/#comments</comments> <pubDate>Tue, 31 Jan 2012 07:33:52 +0000</pubDate> <dc:creator>Vivek Shangari</dc:creator> <category><![CDATA[Coding]]></category> <category><![CDATA[Developers]]></category> <category><![CDATA[CLOS]]></category> <category><![CDATA[Common Lisp]]></category> <category><![CDATA[Common Lisp Object System]]></category> <category><![CDATA[Conard Barski]]></category> <category><![CDATA[control functions]]></category> <category><![CDATA[Daniel G. Bobrow]]></category> <category><![CDATA[Doug Hoyte]]></category> <category><![CDATA[flow control]]></category> <category><![CDATA[functional programming]]></category> <category><![CDATA[James Hague]]></category> <category><![CDATA[Jon L White]]></category> <category><![CDATA[LFY January 2012]]></category> <category><![CDATA[Lisp]]></category> <category><![CDATA[Lisp: Tears of Joy series]]></category> <category><![CDATA[Michael Feathers]]></category> <category><![CDATA[object interfaces]]></category> <category><![CDATA[object-oriented programming]]></category> <category><![CDATA[oo approach]]></category> <category><![CDATA[oo programming]]></category> <category><![CDATA[programming]]></category> <category><![CDATA[programming style]]></category> <category><![CDATA[recursion]]></category> <category><![CDATA[Richard P Gabriel]]></category><guid isPermaLink="false">http://www.linuxforu.com/?p=9429</guid> <description><![CDATA[Lisp has been hailed as the world&#8217;s most powerful programming language. But only the top percentile of programmers use it because of its cryptic syntax and academic reputation. This is rather unfortunate, since...]]></description> <content:encoded><![CDATA[<p><img class="aligncenter size-large wp-image-9431" title="Time to Lisp" src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/lisp-tear-of-joy-590x363.jpg?d9c344" alt="Time to Lisp" width="590" height="363" /><div class="introduction">Lisp has been hailed as the world&#8217;s most powerful programming language. But only the top percentile of programmers use it because of its cryptic syntax and academic reputation. This is rather unfortunate, since Lisp isn&#8217;t that hard to grasp. If you want to be among the crème de la crème, <a href="http://www.linuxforu.com/tag/lisp-tears-of-joy-series/" title="Series of articles on Lisp">this series</a> is for you. This is the eighth article in the series that began in <a href="http://www.linuxforu.com/2011/06/lisp-tears-of-joy-part-1/" title="Lisp: Tears of Joy, Part 1">June 2011</a>.</div><p>In rare moments of self-reflection, when I allow myself to doubt my skills as a Lisp evangelist, I sometimes wonder if I have left behind some of my fellow programmers who favour the object-oriented style of programming. Just because I have been focusing on Lisp as a functional programming paradigm, it doesn&#8217;t mean we don&#8217;t have a role for you in our plans of world domination. Read on to know where you fit in.</p><h2>Functional vs object-oriented (OO) programming</h2><p>With an OO approach, programmers write code that describes in exacting detail the steps that the computer must take to accomplish the goal. They focus on how to perform tasks, and how to track changes in state. They would use loops, conditions and method calls as their primary flow control, and instances of structures or classes as primary manipulation units. OO tries to control state behind object interfaces.</p><p>In contrast, functional programming (FP) involves composing the problem as a set of functions to be executed. FP programmers focus on what information is desired and what transformations are required, by carefully defining the input to each function and what each function returns. They would use function calls, including recursion, as their primary flow control, functions as first-class objects and data collections as primary manipulation units. FP tries to minimise state by using pure functions as much as possible.</p><p><a href="http://twitter.com/#!/mfeathers/status/29581296216">According to Michael Feathers</a>: &#8220;OO makes code understandable by encapsulating moving parts. FP makes code understandable by minimising moving parts.&#8221;</p><p>Conard Barski points out that the critics of the OO programming style may complain that object-oriented techniques force data to be hidden away in a lot of disparate places by requiring them to live inside many different objects. Having data located in disparate places can make programs difficult to understand, especially if that data changes over time.</p><p>Therefore, many Lispers prefer to use functional techniques over object-oriented techniques, though the two can often be used together &#8212; with some care. Nonetheless, there are still many domains in which object-oriented techniques are invaluable, such as in user interface programming or simulation programming.</p><p>On the other hand, James Hague, in his assessment of functional programming argues that, &#8220;100 per cent pure functional programming doesn&#8217;t work. Even 98 per cent pure functional programming doesn&#8217;t work. But if the slider between functional purity and 1980s BASIC-style imperative messiness is kicked down a few notches &#8212; say to 85 per cent &#8212; then it really does work. You get all the advantages of functional programming, but without the extreme mental effort and un-maintainability that increases as you get closer and closer to perfectly pure.&#8221;</p><h2>CLOS</h2><p>If OO is what gets you going, Common Lisp offers the most sophisticated object-oriented programming framework of any major programming language. It&#8217;s called Common Lisp Object System (CLOS). It is customisable at a fundamental level, using the Meta-Object Protocol (MOP). It has been claimed that there&#8217;s really nothing like it anywhere else in programming. It lets you control incredibly complex software without losing control over the code.</p><p>Let the tears of joy flow&#8230;</p><h2>Object-oriented programming in Common Lisp</h2><h3>What is CLOS?</h3><h4>#1: It is a layered system designed for flexibility.</h4><p>One of the design goals of CLOS is to provide a set of layers that separate different programming language concerns from one another. The first level of the Object System provides a programmatic interface to object-oriented programming. This level is designed to meet the needs of most serious users, and to provide a syntax that is crisp and understandable.</p><p>The second level provides a functional interface into the heart of the Object System. This level is intended for programmers who are writing very complex software or a programming environment. The first level is written in terms of this second level.</p><p>The third level provides the tools for programmers who are writing their own object-oriented language. It allows access to the primitive objects and operators of the Object System. It is this level at which the implementation of the Object System itself is based.</p><p>The layered design of CLOS is founded on the meta-object protocol, a protocol that is used to define the characteristics of an object-oriented system. Using the meta-object protocol, other functional or programmatic interfaces to the Object System, as well as other object systems, can be written.</p><h4>#2: It is based on the concept of generic functions rather than on message-passing.</h4><p>This choice is made for two reasons:</p><ol><li>there are some problems with message-passing in operations of more than one argument;</li><li>the concept of generic functions is a generalisation of the concept of ordinary Lisp functions.</li></ol><p>A key concept in object-oriented systems is that given an operation and a tuple of objects on which to apply the operation, the code that is most appropriate to perform the operation is selected, based on the classes of the objects.</p><p>In most message-passing systems, operations are essentially properties of classes, and this selection is made by packaging a message that specifies the operation and the objects to which it applies, before sending that message to a suitable object. That object then takes responsibility for selecting the appropriate piece of code. These pieces of code are called methods.</p><h4>#3: It is a multiple inheritance system.</h4><p>Another key concept in object-oriented programming is the definition of structure and behaviour on the basis of the class of an object. Classes thus impose a type system &#8212; the code that is used to execute operations on objects depends on the classes of the objects. The sub-class mechanism allows classes to be defined that share the structure and the behaviour of other classes. This sub-classing is a tool for modularisation of programs.</p><h4>#4: It provides a powerful method combination facility.</h4><p>Method combination is used to define how the methods that are applicable to a set of arguments can be combined to provide the values of a generic function. In many object-oriented systems, the most specific applicable method is invoked, and that method may invoke other, less specific methods.</p><p>When this happens, there is often a combination strategy at work, but that strategy is distributed throughout the methods as local control structure. Method combination brings the notion of a combination strategy to the surface, and provides a mechanism for expressing that strategy.</p><h4>#5: The primary entities of the system are all first-class objects.</h5><p>In the Common Lisp Object System, generic functions and classes are first-class objects with no intrinsic names. It is possible and useful to create and manipulate anonymous generic functions and classes. The concept of &#8220;first-class&#8221; is important in Lisp-like languages. A first-class object is one that can be explicitly made and manipulated; it can be stored in any location that can hold general objects.</p><h5>What CLOS is not</h3><p>It does not make for a great pickup conversation at the bar. I tried. It did not work!</p><p>It also does not attempt to solve problems of encapsulation. The inherited structure of a class depends on the names of the internal parts of the classes from which it inherits. CLOS does not support subtractive inheritance. Within Common Lisp, there is a primitive module system that can be used to help create separate internal namespaces.</p><h3>Classes</h3><p>The <code>defclass</code> macro is used to define a new class. The definition of a class consists of its name, a list of its direct super-classes, a set of slot specifiers and a set of class options. The direct super-classes of a class are those from which the new class inherits structure and behaviour. When a class is defined, the order in which its direct super-classes are mentioned in the <code>defclass</code> form defines a local precedence order on the class and those super-classes. The local precedence order is represented as a list consisting of the class, followed by its direct super-classes, in the order mentioned in the <code>defclass</code> form. The following two classes define a representation of a point in space. The <code>x-y-position</code> class is a sub-class of the <code>position</code> class:</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (defclass position () ())

&gt; (defclass x-y-position (position)
      ((x :initform 0)
       (y :initform 0))
     (:accessor-prefix position-))</pre><p>The <code>position</code> class is useful if we want to create other sorts of representations for spatial positions. The <code>x</code> and <code>y</code> coordinates are initialised to 0 in all instances, unless explicit values are supplied for them. To refer to the x coordinate of an instance of <code>x-y-position</code>, you would write:</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (position-x position)</pre><p>To alter the x coordinate of that instance, you would write:</p><pre class="brush: text; gutter: false; first-line: 1">(setf (position-x position) new-x)</pre><p>The macro <code>defclass</code> is part of the Object System programmatic interface and, as such, is on the first of the three levels of the Object System.</p><h3>Generic functions</h3><p>The class-specific operations of the Common Lisp Object System are provided by generic functions and methods. A generic function is one whose behaviour depends on the classes or identities of the arguments supplied to it. The methods associated with the generic function define the class-specific operations of the generic function.</p><p>Like an ordinary Lisp function, a generic function takes arguments, performs a series of operations and returns values. An ordinary function has a single body of code that is always executed when the function is called. A generic function is able to perform different series of operations and to combine the results of the operations in different ways, depending on the class or identity of one or more of its arguments.</p><p>Generic functions are defined by means of the <code>defgeneric-options</code> and <code>defmethod</code> macros. The <code>defgeneric-options</code> macro is designed to allow for the specification of properties that pertain to the generic function as a whole, and not just to individual methods. The <code>defmethod</code> form is used to define a method. If there is no generic function of the given name, however, it automatically creates a generic function with default values for the argument precedence order (left-to-right, as defined by the lambda-list), the generic function class (the class <code>standard-generic-function</code>), the method class (the class <code>standard-method</code>) and the method combination type (<code>standard-method combination</code>).</p><h3>Methods</h3><p>The class-specific operations provided by generic functions are themselves defined and implemented by methods. The class or identity of each argument to the generic function indicates which method or methods are eligible to be invoked.</p><p>A method object contains a method function, an ordered set of parameter specialisers that specify when the given method is applicable, and an ordered set of qualifiers that are used by the method combination facility to distinguish between methods.</p><p>The <code>defmethod</code> macro is used to create a method object. A <code>defmethod</code> form contains the code that is to be run when the arguments to the generic function cause the method that it defines, to be selected. If a <code>defmethod</code> form is evaluated, and a method object corresponding to the given generic function name, parameter specialisers and qualifiers already exists, then the new definition replaces the old.</p><p>Generic functions can be used to implement a layer of abstraction on top of a set of classes. For example, the <code>x-y-position</code> class can be viewed as containing information in polar coordinates.</p><p>Two methods have been defined &#8212; <code>position-rho</code> and <code>position-theta</code>, that calculate the &#961; and &#920; coordinates given an instance of <code>x-y-position</code>:</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (defmethod position-rho ((pos x-y-position))
      (let ((x (position-x pos))
            (y (position-y pos)))
         (sqrt (+ (* x x) (* y y)))))

&gt; (defmethod position-theta ((pos x-y-position))
     (atan (position-y pos) (position-x pos)))</pre><p>It is also possible to write methods that update the &#8220;virtual slots&#8221; <code>position-rho</code> and <code>position-theta</code>:</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (defmethod-setf position-rho ((pos x-y-position)) (rho)
      (let* ((r (position-rho pos))
           (ratio (/ rho r)))
        (setf (position-x pos) (* ratio (position-x pos)))
        (setf (position-y pos) (* ratio (position-y pos)))))

&gt; (defmethod-setf position-theta ((pos x-y-position)) (theta)
      (let ((rho (position-rho pos)))
       (setf (position-x pos) (* rho (cos theta)))
       (setf (position-y pos) (* rho (sin theta)))))</pre><p>To update the &#961;-coordinate you may write:</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (setf (position-rho pos) new-rho)</pre><p>This is precisely the same syntax that would be used if the positions were explicitly stored as polar coordinates.</p><h3>Class redefinition</h3><p>The Common Lisp Object System provides a powerful class-redefinition facility.</p><p>When a <code>defclass</code> form is evaluated, and a class with the given name already exists, the existing class is redefined. Redefining a class modifies the existing class object to reflect the new class definition.</p><p>You may define methods on the generic function <code>class-changed</code> to control the class redefinition process. This generic function is invoked automatically by the system after <code>defclass</code> has been used to redefine an existing class; for example, suppose it becomes apparent that the application that requires representing positions uses polar coordinates more than it uses rectangular coordinates. It might make sense to define a sub-class of <code>position</code> that uses polar coordinates:</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (defclass rho-theta-position (position)
      ((rho :initform 0)
      (theta :initform 0))
    (:accessor-prefix position-))</pre><p>The instances of <code>x-y-position</code> can be automatically updated by defining a class-changed method:</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (defmethod class-changed ((old x-y-position)
                          (new rho-theta-position))
;; Copy the position information from old to new to make new
;; be a rho-theta-position at the same position as old.
     (let ((x (position-x old))
           (y (position-y old)))
        (setf (position-rho new) (sqrt (+ (* x x) (* y y)))
              (position-theta new) (atan y x))))</pre><p>At this point, we can change an instance of the class <code>x-y-position</code>, <code>p1</code>, to be an instance of <code>rho-theta-position</code> by using change-class:</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (change-class p1 &#039;rho-theta-position)</pre><h3>Inheritance</h3><p>Inheritance is the key to program modularity within CLOS. A typical object-oriented program consists of several classes, each of which defines some aspect of behaviour. New classes are defined by including the appropriate classes as super-classes, thus gathering the desired aspects of behaviour into one class.</p><p>In general, slot descriptions are inherited by sub-classes. That is, slots defined by a class are usually slots implicitly defined by any sub-class of that class, unless the sub-class explicitly shadows the slot definition. A class can also shadow some of the slot options declared in the <code>defclass</code> form of one of its super-classes by providing its own description for that slot.</p><p>A sub-class inherits methods in the sense that any method applicable to an instance of a class is also applicable to instances of any sub-class of that class (all other arguments to the method being the same).</p><p>The inheritance of methods acts the same way regardless of whether the method was created by using <code>defmethod</code> or by using one of the <code>defclass</code> options that cause methods to be generated automatically.</p><p>I hope with this article I have managed to convince OO programmers that Lisp is generous enough to cater to your style of thinking. Stick with me, and I promise that you won&#8217;t be disappointed. So far we&#8217;ve seen how to fit the nuts and bolts into the engine. Next month, we&#8217;ll learn how to paint it a nice shiny red&#8230; I am referring to Graphical Programming in Lisp!</p><h5>References</h5><ul><li><em>Let Over Lambda</em>, Doug Hoyte</li><li><em>CLOS: Integrating Object-Oriented and Functional programming</em>, Richard P. Gabriel, Jon L White, Daniel G. Bobrow</li></ul><div id="crp_related"><h5>Related Posts:</h5><ul><li><a href="http://www.linuxforu.com/2011/09/lisp-tears-of-joy-part-4/" rel="bookmark" class="crp_title">Lisp: Tears of Joy, Part 4</a></li><li><a href="http://www.linuxforu.com/2011/12/lisp-tears-of-joy-part-7/" rel="bookmark" class="crp_title">Lisp: Tears of Joy, Part 7</a></li><li><a href="http://www.linuxforu.com/2011/10/lisp-tears-of-joy-part-5/" rel="bookmark" class="crp_title">Lisp: Tears of Joy, Part 5</a></li><li><a href="http://www.linuxforu.com/2011/12/loading-library-files-in-cpp/" rel="bookmark" class="crp_title">Loading Library Files in C++</a></li><li><a href="http://www.linuxforu.com/2011/11/lisp-tears-of-joy-part-6/" rel="bookmark" class="crp_title">Lisp: Tears of Joy, Part 6</a></li></ul></div>Tags: <a href="http://www.linuxforu.com/tag/clos/" title="CLOS" rel="tag">CLOS</a>, <a href="http://www.linuxforu.com/tag/common-lisp/" title="Common Lisp" rel="tag">Common Lisp</a>, <a href="http://www.linuxforu.com/tag/common-lisp-object-system/" title="Common Lisp Object System" rel="tag">Common Lisp Object System</a>, <a href="http://www.linuxforu.com/tag/conard-barski/" title="Conard Barski" rel="tag">Conard Barski</a>, <a href="http://www.linuxforu.com/tag/control-functions/" title="control functions" rel="tag">control functions</a>, <a href="http://www.linuxforu.com/tag/daniel-g-bobrow/" title="Daniel G. Bobrow" rel="tag">Daniel G. Bobrow</a>, <a href="http://www.linuxforu.com/tag/doug-hoyte/" title="Doug Hoyte" rel="tag">Doug Hoyte</a>, <a href="http://www.linuxforu.com/tag/flow-control/" title="flow control" rel="tag">flow control</a>, <a href="http://www.linuxforu.com/tag/functional-programming/" title="functional programming" rel="tag">functional programming</a>, <a href="http://www.linuxforu.com/tag/james-hague/" title="James Hague" rel="tag">James Hague</a>, <a href="http://www.linuxforu.com/tag/jon-l-white/" title="Jon L White" rel="tag">Jon L White</a>, <a href="http://www.linuxforu.com/tag/lfy-january-2012/" title="LFY January 2012" rel="tag">LFY January 2012</a>, <a href="http://www.linuxforu.com/tag/lisp/" title="Lisp" rel="tag">Lisp</a>, <a href="http://www.linuxforu.com/tag/lisp-tears-of-joy-series/" title="Lisp: Tears of Joy series" rel="tag">Lisp: Tears of Joy series</a>, <a href="http://www.linuxforu.com/tag/michael-feathers/" title="Michael Feathers" rel="tag">Michael Feathers</a>, <a href="http://www.linuxforu.com/tag/object-interfaces/" title="object interfaces" rel="tag">object interfaces</a>, <a href="http://www.linuxforu.com/tag/object-oriented-programming/" title="object-oriented programming" rel="tag">object-oriented programming</a>, <a href="http://www.linuxforu.com/tag/oo-approach/" title="oo approach" rel="tag">oo approach</a>, <a href="http://www.linuxforu.com/tag/oo-programming/" title="oo programming" rel="tag">oo programming</a>, <a href="http://www.linuxforu.com/tag/programming/" title="programming" rel="tag">programming</a>, <a href="http://www.linuxforu.com/tag/programming-style/" title="programming style" rel="tag">programming style</a>, <a href="http://www.linuxforu.com/tag/recursion/" title="recursion" rel="tag">recursion</a>, <a href="http://www.linuxforu.com/tag/richard-p-gabriel/" title="Richard P Gabriel" rel="tag">Richard P Gabriel</a><br /> ]]></content:encoded> <wfw:commentRss>http://www.linuxforu.com/2012/01/lisp-tears-of-joy-part-8/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Developing Applications on QT, Part 1</title><link>http://www.linuxforu.com/2012/01/developing-applications-qt-part-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=developing-applications-qt-part-1</link> <comments>http://www.linuxforu.com/2012/01/developing-applications-qt-part-1/#comments</comments> <pubDate>Tue, 31 Jan 2012 06:26:29 +0000</pubDate> <dc:creator>Manoj Kumar</dc:creator> <category><![CDATA[Coding]]></category> <category><![CDATA[Developers]]></category> <category><![CDATA[application development]]></category> <category><![CDATA[application performance]]></category> <category><![CDATA[C/C++]]></category> <category><![CDATA[cpp]]></category> <category><![CDATA[desktop applications]]></category> <category><![CDATA[GUI]]></category> <category><![CDATA[Java]]></category> <category><![CDATA[LFY January 2012]]></category> <category><![CDATA[Microsoft Windows]]></category> <category><![CDATA[POSIX]]></category> <category><![CDATA[Qt]]></category> <category><![CDATA[Qt applications]]></category> <category><![CDATA[Qt Creator]]></category> <category><![CDATA[Qt Designer]]></category> <category><![CDATA[Qt development]]></category> <category><![CDATA[Qt GUI applications]]></category> <category><![CDATA[Qt Linguist]]></category> <category><![CDATA[software frameworks]]></category> <category><![CDATA[Sun Microsystems]]></category> <category><![CDATA[Symbian]]></category> <category><![CDATA[Trolltech]]></category> <category><![CDATA[xml]]></category><guid isPermaLink="false">http://www.linuxforu.com/?p=9422</guid> <description><![CDATA[This article introduces application development using the Qt GUI framework. There was a time when all desktop applications were developed from scratch. Then came the concept of code reuse. Static and shared libraries...]]></description> <content:encoded><![CDATA[<p><img src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/qt-dev-open-590x393.jpg?d9c344" alt="It&#039;s Qt" title="It&#039;s Qt" width="590" height="393" class="aligncenter size-large wp-image-9426" /><div class="introduction">This article introduces application development using the Qt GUI framework.</div><p>There was a time when all desktop applications were developed from scratch. Then came the concept of code reuse. Static and shared libraries were created for use in application development, but developers didn&#8217;t stop at that; they came up with software frameworks. Though libraries and frameworks seem to functionally be the same, there are some major differences between them, which should be understood:</p><ul><li>Libraries offer reusability of functionality, whereas frameworks offer reusability of behaviour. For example, a library may provide classes for TCP and UDP sockets, while a framework will provide a class for an abstract socket.</li><li>A library may provide functions used for signals/events, but the framework function is how they interact with the system and other components.</li><li>Libraries are called from application code, but the framework calls application code &#8212; or, you can say, provides services to the code.</li></ul><h2>Desktop applications</h2><p>Desktop applications are very platform-specific. An application compiled for Linux cannot be directly executed on another OS without some sort of emulation, due to differences in system calls and libraries between OSs. A big question was how to write platform-independent applications.</p><p>One method was to develop libraries for each platform, keeping application code the same and recompiling for each target platform. This does make life easier for developers &#8212; but then everything changed with the revolutionary concept of virtual machines from Sun Microsystems, which gave the world the platform-independent Java programming language. Java applications run on the Java Virtual Machine (JVM). Code developed once can be deployed to every platform that has a JVM for it.</p><p>But everything comes with a price. In Java&#8217;s case, the price was application performance. The performance of Java applications is not as good as of C/C++ applications compiled to platform-native code. Another problem is the large memory footprint. No doubt Java is still a leading language, but these days we have some really big data applications (for example, in biotech) with very high performance requirements. So again, the need is to develop applications compilable to native code. Application development using C is time-consuming, while C++ is a better option. We have some frameworks that support C++ for application development. The Qt framework is one of them.</p><h2>Introducing Qt</h2><p><a href="http://qt.nokia.com/">Qt</a> is a cross-platform application framework developed by Trolltech and presently owned by Nokia. Its APIs are for C++. Qt has been extensively used by application developers to develop cross-platform applications.</p><p>Qt can help with graphical application development, network applications, database and multimedia applications, handling XML and 3D, painting, drawing and Web access. As far as platform support is concerned, it supports Linux, Mac OS, Windows, Meego, Embedded Linux and Symbian.</p><h2>Qt architecture</h2><p>In Figure 1, you can see a minimal architecture diagram.</p><div id="attachment_9424" class="wp-caption aligncenter" style="width: 590px"><a href="http://cdn.linuxforu.com/wp-content/uploads/2012/01/fig-1.png?d9c344"><img src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/fig-1-590x179.png?d9c344" alt="Qt architecture" title="Qt architecture" width="590" height="179" class="size-large wp-image-9424" /></a><p class="wp-caption-text">Figure 1: Qt architecture</p></div><p>The top layer is C++ program code. Below that are Qt classes for GUI, WebKit, databases, etc., and then an OS-specific support layer. Earlier, Qt also supported Java; its Java-based version was called Jambie. As Qt development progressed, it was getting difficult to support both C++ and Java, so the decision was made to support only C++.</p><h2>Qt installation</h2><p>Installation methods differ by OS. On Ubuntu 10.04 LTS, I installed Qt via the Synaptic package manager &#8212; install the <code>qtcreator</code> package; dependency resolution will install Qt Assistant, Qt Designer, Qt Linguist and Qt Creator.</p><p>If you want to try out the latest Qt release, you can download the offline installer from their <a href="http://qt.nokia.com/downloads">official  website</a> and install it. Just <code>chmod</code> the installer file to make it executable and run it, and then follow the prompts.</p><h2>A &#8216;Hello World&#8217; program (non-GUI)</h2><p>Open a terminal. Create a directory (first) and create a simple &#8220;Hello World&#8221; program with the following code:</p><pre class="brush: cpp; gutter: false; first-line: 1">#include&lt;QtCore&gt;
int main(){
    qDebug() &lt;&lt; &quot;Hello world\n&quot;;
}</pre><p>The included header file QtCore contains declarations for classes that do not use a GUI. We will look at these in detail in later articles. For now, just use the <code>qDebug</code> class, which outputs debugging messages to the console and is equivalent to <code>cout</code> in traditional C++ programming.</p><p>So how does one compile it? The Trolltech people came out with an easy solution to support cross-platform compilation. First, a project file should be created, and then a <code>Makefile</code> is created using it. Then, just run <code>make</code> to compile the program. When you install QT Creator, a utility called <code>qmake</code> is also installed. This is a cross-platform <code>Makefile</code> generator for Qt. Check out its man pages for more. Run <code>qmake -project</code> to create a project file (<code>.pro</code> extension, with its name that of the containing directory, i.e., first).</p><pre class="brush: text; gutter: false; first-line: 1">$ cat first.pro
######################################################################
# Automatically generated by qmake (2.01a) Mon Nov 28 05:49:29 2011
######################################################################

TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .

# Input
SOURCES += main.cpp</pre><p>You can create both applications and libraries; the value of <code>TEMPLATE</code> is <code>app</code>, indicating this is an application. I will cover library development in later articles. The <code>SOURCES</code> entry lists source files in the project, about which  more details appear later in this article series.</p><p>Now, let us generate the <code>Makefile</code> with <code>qmake</code>. It&#8217;s a long file &#8212; it may contain up to 200 lines. Run <code>make</code> to create the executable file:</p><pre class="brush: text; gutter: false; first-line: 1">$ make
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o main.o main.cpp
make: Circular all &lt;- first dependency dropped.
g++ -Wl,-O1 -o first main.o    -L/usr/lib -lQtGui -lQtCore -lpthread</pre><p>In the last line, you can see that our sample program uses the POSIX thread library too. Run the file with <code>./first</code> to see the output &#8220;Hello world&#8221;. It&#8217;s done! We have successfully compiled our first program.</p><h2>Sample GUI program</h2><p>Qt has an option to create UI files using a drag-and-drop method, which we will explore in the next article. For now, let us hand-code a sample simple GUI program:</p><pre class="brush: cpp; gutter: false; first-line: 1">

#include&lt;QApplication&gt;
#include&lt;QLabel&gt;

int main(int argc, char *argv[]){
    QApplication a(argc, argv);
    QLabel    label;
    label.setText(&quot;Hello World&quot;);
    label.show();
    a.exec();
}</pre><p>In the first example, there was no GUI. The program terminates when main returns. However, in GUI programs, we can&#8217;t do that, or the application will not be usable. We want the GUI to run until the user closes the window. To achieve this, run your program in a loop till this happens, so you use the event-loop-based class <code>QApplication</code>. When you create an object of this class and call its <code>exec()</code> function, main never returns. The application keeps on waiting for user input events.</p><p>The second header file contains the class <code>QLabel</code>, a simple widget used to display text. Instantiate it and set its text to &#8220;Hello World&#8221;. When a widget&#8217;s <code>show()</code> function is called, then it becomes a window. So the widget label will be seen like a window. In Figure 2, you can see the resultant label window with title bar. You can resize the output window simply with the help of the mouse.</p><div id="attachment_9423" class="wp-caption aligncenter" style="width: 422px"><img src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/fig2.png?d9c344" alt="Widget label" title="Widget label" width="422" height="256" class="size-full wp-image-9423" /><p class="wp-caption-text">Figure 2: Widget label</p></div><p>In the next articles, we will cover the core classes of Qt. In the meanwhile, I suggest you go through the <a href="http://doc.qt.nokia.com/">official documentation</a>.</p><div class="imagecredit">Feature image courtesy: <a href="http://www.flickr.com/photos/nokia_fan/5072435170/">nokia_fan</a>. Reused under the terms of CC-BY-NC 2.0 License.</div><div id="crp_related"><h5>Related Posts:</h5><ul><li><a href="http://www.linuxforu.com/2011/12/loading-library-files-in-cpp/" rel="bookmark" class="crp_title">Loading Library Files in C++</a></li><li><a href="http://www.linuxforu.com/2011/06/qemu-for-embedded-systems-development-part-1/" rel="bookmark" class="crp_title">Using QEMU for Embedded Systems Development, Part 1</a></li><li><a href="http://www.linuxforu.com/2011/08/integrating-google-app-engine-and-eclipse/" rel="bookmark" class="crp_title">Integrating Google App Engine and Eclipse</a></li><li><a href="http://www.linuxforu.com/2011/08/joy-of-programming-calling-virtual-functions-from-constructors/" rel="bookmark" class="crp_title">Joy of Programming: Calling Virtual Functions from Constructors</a></li><li><a href="http://www.linuxforu.com/2011/10/lets-play-with-codeigniter/" rel="bookmark" class="crp_title">Let&#8217;s Play with CodeIgniter</a></li></ul></div>Tags: <a href="http://www.linuxforu.com/tag/application-development/" title="application development" rel="tag">application development</a>, <a href="http://www.linuxforu.com/tag/application-performance/" title="application performance" rel="tag">application performance</a>, <a href="http://www.linuxforu.com/tag/cc/" title="C/C++" rel="tag">C/C++</a>, <a href="http://www.linuxforu.com/tag/cpp/" title="cpp" rel="tag">cpp</a>, <a href="http://www.linuxforu.com/tag/desktop-applications/" title="desktop applications" rel="tag">desktop applications</a>, <a href="http://www.linuxforu.com/tag/gui/" title="GUI" rel="tag">GUI</a>, <a href="http://www.linuxforu.com/tag/java/" title="Java" rel="tag">Java</a>, <a href="http://www.linuxforu.com/tag/lfy-january-2012/" title="LFY January 2012" rel="tag">LFY January 2012</a>, <a href="http://www.linuxforu.com/tag/microsoft-windows/" title="Microsoft Windows" rel="tag">Microsoft Windows</a>, <a href="http://www.linuxforu.com/tag/posix/" title="POSIX" rel="tag">POSIX</a>, <a href="http://www.linuxforu.com/tag/qt/" title="Qt" rel="tag">Qt</a>, <a href="http://www.linuxforu.com/tag/qt-applications/" title="Qt applications" rel="tag">Qt applications</a>, <a href="http://www.linuxforu.com/tag/qt-creator/" title="Qt Creator" rel="tag">Qt Creator</a>, <a href="http://www.linuxforu.com/tag/qt-designer/" title="Qt Designer" rel="tag">Qt Designer</a>, <a href="http://www.linuxforu.com/tag/qt-development/" title="Qt development" rel="tag">Qt development</a>, <a href="http://www.linuxforu.com/tag/qt-gui-applications/" title="Qt GUI applications" rel="tag">Qt GUI applications</a>, <a href="http://www.linuxforu.com/tag/qt-linguist/" title="Qt Linguist" rel="tag">Qt Linguist</a>, <a href="http://www.linuxforu.com/tag/software-frameworks/" title="software frameworks" rel="tag">software frameworks</a>, <a href="http://www.linuxforu.com/tag/sun-microsystems/" title="Sun Microsystems" rel="tag">Sun Microsystems</a>, <a href="http://www.linuxforu.com/tag/symbian/" title="Symbian" rel="tag">Symbian</a>, <a href="http://www.linuxforu.com/tag/trolltech/" title="Trolltech" rel="tag">Trolltech</a>, <a href="http://www.linuxforu.com/tag/xml/" title="xml" rel="tag">xml</a><br /> ]]></content:encoded> <wfw:commentRss>http://www.linuxforu.com/2012/01/developing-applications-qt-part-1/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Working with MTD Devices</title><link>http://www.linuxforu.com/2012/01/working-with-mtd-devices/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=working-with-mtd-devices</link> <comments>http://www.linuxforu.com/2012/01/working-with-mtd-devices/#comments</comments> <pubDate>Tue, 31 Jan 2012 05:28:39 +0000</pubDate> <dc:creator>Mohan Lal Jangir</dc:creator> <category><![CDATA[Coding]]></category> <category><![CDATA[Developers]]></category> <category><![CDATA[application developers]]></category> <category><![CDATA[bad blocks]]></category> <category><![CDATA[C]]></category> <category><![CDATA[Data storage device]]></category> <category><![CDATA[Disk sector]]></category> <category><![CDATA[driver]]></category> <category><![CDATA[file systems]]></category> <category><![CDATA[flash devices]]></category> <category><![CDATA[flash memory]]></category> <category><![CDATA[flash memory chips]]></category> <category><![CDATA[Hard disk drive]]></category> <category><![CDATA[kernel]]></category> <category><![CDATA[kernel programmer]]></category> <category><![CDATA[LFY January 2012]]></category> <category><![CDATA[Memory Technology]]></category> <category><![CDATA[MTD]]></category> <category><![CDATA[MTD Devices]]></category> <category><![CDATA[NAND/NOR-based flash]]></category> <category><![CDATA[partitions]]></category> <category><![CDATA[removable media]]></category> <category><![CDATA[scheduler]]></category> <category><![CDATA[sd cards]]></category> <category><![CDATA[USB flash drive]]></category> <category><![CDATA[volatile data]]></category><guid isPermaLink="false">http://www.linuxforu.com/?p=9415</guid> <description><![CDATA[This article shows how kernel and application developers (in C) can make use of MTD in Linux. MTD (Memory Technology Devices) are NAND/NOR-based flash memory chips used for storing non-volatile data like boot...]]></description> <content:encoded><![CDATA[<p><img src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/mtd-590x315.png?d9c344" alt="Memory Technology Devices" title="Memory Technology Devices" width="590" height="315" class="aligncenter size-large wp-image-9418" /><div class="introduction">This article shows how kernel and application developers (in C) can make use of MTD in Linux.</div><p>MTD (Memory Technology Devices) are NAND/NOR-based flash memory chips used for storing non-volatile data like boot images and configurations. Readers are cautioned not to get confused with USB sticks, SD cards, etc., which are also called flash devices, but are not MTD devices. The latter are generally found on development boards, used to store boot loaders, an OS, etc.</p><p>Even though MTD devices are for data storage, they differ from hard disks and RAM in several aspects. The biggest difference is that while hard disk sectors are rewritable, MTD device sectors must be erased before rewriting &#8212; which is why they are more commonly called erase-blocks. Second, hard disk sectors can be rewritten several times without wearing out the hardware, but MTD device sectors have a limited life and are not usable after about 10^3-10^5 erase operations. The worn out erase-blocks are called bad blocks and the software must take care not to use such blocks.</p><p>Like hard disks, MTD devices can be partitioned and can therefore act as independent devices. On a system with one or more MTD devices, device and partition information can be obtained from the <code>/proc/mtd</code> file. A typical <code>/proc/mtd</code> file is as follows:</p><pre class="brush: text; gutter: false; first-line: 1">cat /proc/mtd
dev:  size    erasesize name
mtd0: 000a0000 00020000 &quot;misc&quot;
mtd1: 00420000 00020000 &quot;recovery&quot;
mtd2: 002c0000 00020000 &quot;boot&quot;
mtd3: 0fa00000 00020000 &quot;system&quot;
mtd4: 02800000 00020000 &quot;cache&quot;
mtd5: 0af20000 00020000 &quot;userdata&quot;</pre><p>A partitioned MTD device can be depicted as in Figure 1, which shows the relation between an MTD device, a partition and a sector.</p><div id="attachment_9416" class="wp-caption aligncenter" style="width: 450px"><img src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/figure-1-an-MTD-Device.jpg?d9c344" alt="An MTD device" title="An MTD device" width="450" height="477" class="size-full wp-image-9416" /><p class="wp-caption-text">Figure 1: An MTD device</p></div><p>As already said, MTD write operations are different from usual storage devices. Therefore, before we move further, let&#8217;s understand how write operations take place on MTD devices. Figure 2 shows a typical write case.</p><div id="attachment_9417" class="wp-caption aligncenter" style="width: 590px"><img src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/figure-2-590x172.jpg?d9c344" alt="An MTD write operation" title="An MTD write operation" width="590" height="172" class="size-large wp-image-9417" /><p class="wp-caption-text">Figure 2: An MTD write operation</p></div><p>The left-most part shows a sector that has some data at the end. The rest of the sector has not been written since the last erase. A user wants to write &#8220;new data 1&#8243; to this sector at offset 0. Since this part of the sector has already been erased, it is ready to be written and so &#8220;new data 1&#8243; can be directly written to the sector. Later, the user may want to write &#8220;new data 2&#8243;, again at offset 0. To do this, the sector must be erased. Since the sector needs to be erased in entirety, the &#8220;old data&#8221; must be backed up in a temporary buffer. After erasing the complete sector, the &#8220;new data 2&#8243; and &#8220;old data&#8221; must be written at appropriate offsets.</p><p>This procedure is the reason there are specific file systems for MTD devices, like JFFS2 and YAFFFS, and flash translation layers (FTL) like NFTL, INFTL, etc. These FTLs and file systems take special care of MTD device properties to hide complexity from the user.</p><p>In the first section that follows, we will look at how to access, read/write and erase MTD devices from Linux applications. The second section describes the same things in kernel space, so that this article can be useful to both application as well as kernel developers.</p><h2>Accessing MTDs from applications</h2><p>The user must know the device partition to work upon, which can be found from <code>/proc/mtd</code> as shown earlier. Assuming users want to work on the &#8220;userdata&#8221; partition, they must use the <code>/dev/mtd5</code> device.</p><p>The first thing to do is to get information about the MTD device. Use the <code>MEMGETINFO ioctl</code> command, as follows:</p><pre class="brush: c; gutter: true; first-line: 1">#include &lt;stdio.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;sys/ioctl.h&gt;
#include &lt;mtd/mtd-user.h&gt;

int main()
{
    mtd_info_t mtd_info;
    int fd = open(&quot;/dev/mtd5&quot;, O_RDWR);
ioctl(fd, MEMGETINFO, &amp;mtd_info);

    printf(&quot;MTD type: %u\n&quot;, mtd_info.type);
    printf(&quot;MTD total size : %u bytes\n&quot;, mtd_info.size);
    printf(&quot;MTD erase size : %u bytes\n&quot;, mtd_info.erasesize);

    return 0;
}</pre><p>Error handling has been omitted for brevity. The <code>mtd_info_t</code> structure is used with the <code>MEMGETINFO</code> command. The MTD type can be <code>MTD_ABSENT</code>, <code>MTD_RAM</code>, <code>MTD_ROM</code>, <code>MTD_NAND</code>, <code>MTD_NOR</code>, etc., which are defined in the <code>mtd/mtd-abi.h</code> header file. The <code>mtd_info.size</code> indicates the size of the whole device (i.e., the partition, in this case). Finally, <code>mtd_info.erasesize</code> indicates the sector size. During an erase operation, this is the minimum size that can be erased, as we&#8217;ll see later.</p><p>Reading MTD devices is similar to ordinary devices:</p><pre class="brush: c; gutter: false; first-line: 1">/* read something from last sector */
unsigned char buf[64];
lseek(fd, -mtd_info.erasesize, SEEK_END);
read(fd, buf, sizeof(buf));</pre><p>A write operation can be performed in the same way, provided the sector has been erased previously. Finally, we come to the erase operation. Here is an example of erasing a partition, sector by sector:</p><pre class="brush: c; gutter: false; first-line: 1">void erase_partition(mtd_info_t *mtd_info, int fd) {
    erase_info_t ei;
    ei.length = mtd_info-&gt;erasesize;
 
    for(ei.start = 0; ei.start &lt; mtd_info-&gt;size; ei.start += mtd_info-&gt;erasesize) {
        ioctl(fd, MEMUNLOCK, &amp;ei);
        ioctl(fd, MEMERASE, &amp;ei);
    }
}</pre><p>All sectors of the device are writeable after this erase operation. Notice the use of <code>MEMUNLOCK</code> before <code>MEMERASE</code>, which is essential to allow the erase operation.</p><h2>Accessing MTDs from kernel space</h2><p>This section will repeat the functions explained in the previous section, but in kernel space. This needs a separate section since the erase operation is more complex here  &#8211;  the erase operation may sleep and therefore the kernel programmer has to wait until the operation is completed. This is the case for applications too, but the sleep is transparently taken care of by the scheduler.</p><p>As explained earlier, the first MTD information is the <code>mtd_info</code> structure. This is retrieved by iterating through all registered MTD devices:</p><pre class="brush: c; gutter: true; first-line: 1">#include &lt;linux/kernel.h&gt;
#include &lt;linux/mtd/mtd.h&gt;
#include &lt;linux/err.h&gt;

static struct mtd_info *mtd_info = NULL;
 
int init_module(void) {
    int num;
    for(num = 0; num &lt; 64; num++) {
        mtd_info = get_mtd_device(NULL, num);
        if(IS_ERR(mtd_info)) {
            printk(&quot;No device for num %d\n&quot;, num);
            continue;
        }
        if(mtd_info-&gt;type == MTD_ABSENT) {
            put_mtd_device(mtd_info);
            continue;
        }
        if(strcmp(mtd_info-&gt;name, &quot;userdata&quot;)) {
            put_mtd_device(mtd_info);
            continue;
        }
        printk(&quot;MTD type: %u\n&quot;, mtd_info-&gt;type);
        printk(&quot;MTD total size : %u bytes\n&quot;, mtd_info-&gt;size);
        printk(&quot;MTD erase size : %u bytes\n&quot;, mtd_info-&gt;erasesize);
        return 0;
    }
    mtd_info = NULL;
    return 0;
}
 
void cleanup_module(void)

{

if(mtd_info)
        put_mtd_device(mtd_info);
}</pre><p>The above kernel module searches for the &#8220;userdata&#8221; partition. The function <code>get_mtd_device()</code>, when invoked with the first argument <code>NULL</code>, returns the MTD device associated with the minor number specified in the second argument. On a successful search, it increments the reference count of the device. That&#8217;s why, before exiting, a call to <code>put_mtd_device()</code> must be made to release (decrement) the reference count.</p><p>Additionally, the module uses the <code>flag MTD_ABSENT</code> (which is available to applications too). This check is required to function correctly with some probing device drivers used to allocate placeholder MTD devices on systems that have socketed or removable media.</p><p>Having retrieved the <code>mtd_info</code> structure, reading is relatively simple:</p><pre class="brush: c; gutter: false; first-line: 1">/* read something from last sector */
u_char buf[64];

mtd_info-&gt;read(mtd_info, mtd_info.size-mtd_info.erasesize, sizeof(buf), buf);</pre><p>The second argument of the read function specifies the read offset, and the third the length to read. Note that the read operation too may sleep and, therefore, it must not be performed in an interrupt context. The write operation can be performed as follows (assuming the sector has been previously erased):</p><pre class="brush: c; gutter: false; first-line: 1">/* write something to last sector */
mtd_info-&gt;write(mtd_info, mtd_info.size-mtd_info.erasesize, sizeof(buf), buf);</pre><p>As mentioned before, the read, write and erase operations may sleep. Therefore, kernel code must wait for the operation to finish. Here is an example of erasing the partition and waiting to finish the operation:</p><pre class="brush: c; gutter: false; first-line: 1">#include &lt;linux/sched.h&gt;

void erase_partition(struct mtd_info *mtd_info) {
    unsigned int start;
    for(start = 0; start &lt; mtd_info-&gt;size; start += mtd_info-&gt;erasesize)
        erase_sector(mtd_info, start, mtd_info-&gt;erasesize);
}
 
void erase_sector(struct mtd_info *mtd_info, unsigned int start, unsigned int len) 

{
    int ret;
    struct erase_info ei = {0};
    wait_queue_head_t waitq;
    DECLARE_WAITQUEUE(wait, current);
    
    init_waitqueue_head(&amp;waitq);
    ei.addr = start;
    ei.len = mtd_info-&gt;erasesize;
    ei.mtd = mtd_info;
    ei.callback = erase_callback;
    ei.priv = (unsigned long)&amp;waitq;
    ret = mtd_info-&gt;erase(mtd_info, &amp;ei);
    if(!ret)     {
        set_current_state(TASK_UNINTERRUPTIBLE);
        add_wait_queue(&amp;waitq, &amp;wait);
        if (ei.state != MTD_ERASE_DONE &amp;&amp; ei.state != MTD_ERASE_FAILED)
            schedule();
        remove_wait_queue(&amp;waitq, &amp;wait);
        set_current_state(TASK_RUNNING);
 
        ret = (ei.state == MTD_ERASE_FAILED)?-EIO:0;
    }
}
 
void erase_callback (struct erase_info *instr) {
    wake_up((wait_queue_head_t *)instr-&gt;priv);
}</pre><p>The <code>erase_partition()</code> function iterates over all sectors, and erases them with <code>erase_sector()</code>. At the core of <code>erase_sector()</code> is the <code>mtd_info-&gt;erase</code> call, which (as mentioned previously) may sleep. Therefore, <code>erase_sector()</code> prepares a wait queue and a wait queue head.</p><p>After a call to <code>mtd_info-&gt;erase</code>, the function prepares itself to relinquish the CPU (presuming that <code>mtd_info-&gt;erase</code> will sleep) by changing task state to <code>TASK_UNINTERRUPTIBLE</code> and adding itself to the wait queue head. Before relinquishing the CPU, it checks if erase is done, through the <code>ei.state</code> flag. If erase is done successfully, this flag will be set to <code>MTD_ERASE_DONE</code>.</p><p>If the erase operation is not complete, the task relinquishes the CPU by calling <code>schedule()</code>. Later, when the erase operation is complete, the driver calls the callback function provided in <code>ei.callback</code>. Here the task wakes up to itself, then removes itself from the wait queue, changes the task state to <code>TASK_RUNNING</code> and finally, the <code>erase_sector()</code> function returns.</p><p>MTD devices have many more features that can be used by application programmers. ECC (error correction codes) and OOB (out of band) data are some of them. The MTD framework is integrated into the Linux kernel &#8212; therefore it makes working with MTD devices very simple, as we have seen in this article.<div id="crp_related"><h5>Related Posts:</h5><ul><li><a href="http://www.linuxforu.com/2012/01/device-drivers-partitions-hard-disk/" rel="bookmark" class="crp_title">Device Drivers, Part 14: A Dive Inside the Hard Disk for Understanding Partitions</a></li><li><a href="http://www.linuxforu.com/2011/12/loading-library-files-in-cpp/" rel="bookmark" class="crp_title">Loading Library Files in C++</a></li><li><a href="http://www.linuxforu.com/2011/05/decoding-character-device-file-operations/" rel="bookmark" class="crp_title">Device Drivers, Part 6: Decoding Character Device File Operations</a></li><li><a href="http://www.linuxforu.com/2011/12/data-transfers-to-from-usb-devices/" rel="bookmark" class="crp_title">Device Drivers, Part 13: Data Transfer to and from USB Devices</a></li><li><a href="http://www.linuxforu.com/2011/11/socket-api-part-4-datagrams/" rel="bookmark" class="crp_title">The Socket API, Part 4: Datagrams</a></li></ul></div>Tags: <a href="http://www.linuxforu.com/tag/application-developers/" title="application developers" rel="tag">application developers</a>, <a href="http://www.linuxforu.com/tag/bad-blocks/" title="bad blocks" rel="tag">bad blocks</a>, <a href="http://www.linuxforu.com/tag/c/" title="C" rel="tag">C</a>, <a href="http://www.linuxforu.com/tag/data-storage-device/" title="Data storage device" rel="tag">Data storage device</a>, <a href="http://www.linuxforu.com/tag/disk-sector/" title="Disk sector" rel="tag">Disk sector</a>, <a href="http://www.linuxforu.com/tag/driver/" title="driver" rel="tag">driver</a>, <a href="http://www.linuxforu.com/tag/file-systems/" title="file systems" rel="tag">file systems</a>, <a href="http://www.linuxforu.com/tag/flash-devices/" title="flash devices" rel="tag">flash devices</a>, <a href="http://www.linuxforu.com/tag/flash-memory/" title="flash memory" rel="tag">flash memory</a>, <a href="http://www.linuxforu.com/tag/flash-memory-chips/" title="flash memory chips" rel="tag">flash memory chips</a>, <a href="http://www.linuxforu.com/tag/hard-disk-drive/" title="Hard disk drive" rel="tag">Hard disk drive</a>, <a href="http://www.linuxforu.com/tag/kernel/" title="kernel" rel="tag">kernel</a>, <a href="http://www.linuxforu.com/tag/kernel-programmer/" title="kernel programmer" rel="tag">kernel programmer</a>, <a href="http://www.linuxforu.com/tag/lfy-january-2012/" title="LFY January 2012" rel="tag">LFY January 2012</a>, <a href="http://www.linuxforu.com/tag/memory-technology/" title="Memory Technology" rel="tag">Memory Technology</a>, <a href="http://www.linuxforu.com/tag/mtd/" title="MTD" rel="tag">MTD</a>, <a href="http://www.linuxforu.com/tag/mtd-devices/" title="MTD Devices" rel="tag">MTD Devices</a>, <a href="http://www.linuxforu.com/tag/nandnor-based-flash/" title="NAND/NOR-based flash" rel="tag">NAND/NOR-based flash</a>, <a href="http://www.linuxforu.com/tag/partitions/" title="partitions" rel="tag">partitions</a>, <a href="http://www.linuxforu.com/tag/removable-media/" title="removable media" rel="tag">removable media</a>, <a href="http://www.linuxforu.com/tag/scheduler/" title="scheduler" rel="tag">scheduler</a>, <a href="http://www.linuxforu.com/tag/sd-cards/" title="sd cards" rel="tag">sd cards</a>, <a href="http://www.linuxforu.com/tag/usb-flash-drive/" title="USB flash drive" rel="tag">USB flash drive</a>, <a href="http://www.linuxforu.com/tag/volatile-data/" title="volatile data" rel="tag">volatile data</a><br /> ]]></content:encoded> <wfw:commentRss>http://www.linuxforu.com/2012/01/working-with-mtd-devices/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>CodeSport (January 2012)</title><link>http://www.linuxforu.com/2012/01/codesport-january-2012/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=codesport-january-2012</link> <comments>http://www.linuxforu.com/2012/01/codesport-january-2012/#comments</comments> <pubDate>Mon, 30 Jan 2012 08:08:48 +0000</pubDate> <dc:creator>Sandya Mannarswamy</dc:creator> <category><![CDATA[Coding]]></category> <category><![CDATA[Columns]]></category> <category><![CDATA[C/C++]]></category> <category><![CDATA[CodeSport]]></category> <category><![CDATA[compiler optimisation]]></category> <category><![CDATA[computer science]]></category> <category><![CDATA[Dynamic memory allocation]]></category> <category><![CDATA[even integer]]></category> <category><![CDATA[integers]]></category> <category><![CDATA[interview questions]]></category> <category><![CDATA[LFY January 2012]]></category> <category><![CDATA[malloc]]></category> <category><![CDATA[memory management]]></category> <category><![CDATA[odd integers]]></category> <category><![CDATA[programming questions]]></category> <category><![CDATA[puzzles]]></category><guid isPermaLink="false">http://www.linuxforu.com/?p=9369</guid> <description><![CDATA[In this month&#8217;s column, we take a short break from our discussion of compiler optimisations and feature a set of questions for computer science interviews. We have been discussing compiler optimisation over the...]]></description> <content:encoded><![CDATA[<p><img src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/ques.png?d9c344" alt="Questions" title="Questions" width="300" height="392" class="alignright size-full wp-image-9371" /><div class="introduction">In this month&#8217;s column, we take a short break from our discussion of compiler optimisations and feature a set of questions for computer science interviews.</div><p>We have been discussing compiler optimisation over the last few columns. However, a couple of our readers reminded me that we used to feature a set of programming questions for our <a href="http://www.linuxforu.com/2011/12/codesport-december-2011/" title="CodeSport (December 2011)">December column</a> &#8212; and this time, I missed doing that. Thank you, Sunil and Shreya, for the timely reminder. Hence, in this month&#8217;s column, we will take a break from our discussion on inter-procedural optimisations and turn to discussing a few interview questions. Let&#8217;s start off with a few puzzles, followed by programming questions.</p><h2>This month&#8217;s questions</h2><ol><li>Let A be a multi-set of integers consisting of N numbers. You are allowed to pick up two integers at a time. If both are even, or both odd, discard both and insert an even integer. If not, you discard the even integer. Given that there are an even number of odd integers initially in A, can you tell whether the last integer will be even or odd. What is the reasoning behind your answer?</li><li>There is a building with N floors. You are given M balls. You are told that there is an integer K &lt; N such that if the ball is dropped from the floor K or any floor higher than K, it would break. But the ball would not break if you drop it from a floor below K. What is the minimum number of balls that you need to drop to determine K: (a) in the best-case scenario; (b) in the worst-case scenario?</li><li>You have 100 doors in a row, all of which are initially closed. You make 100 passes over these doors, starting with the first door. The first time when you make the pass, you visit every door and toggle the door (i.e., if the door is open, close it; if it is closed, open it). During the second pass, you visit every second door (doors numbered 2, 4, 6, 8, and so on). During the third pass, you visit only every third door (doors marked 3, 6, 9, 12). You repeat these passes until you finish all the 100 passes. Now can you determine what state each door is in after the 100th pass? Which doors are open and which are closed?</li><li>You are given a coin and you have been told to use this for a coin-tossing experiment. You are told that the coin is weighted to come up heads more times than tails. Given such a biased coin, how can you get a fair coin toss?</li><li>You are given a sequence of numbers from 1 to n-1, with two of the numbers repeating twice. For instance, instead of &lt;1,2,3,4,5&gt;, you are given &lt;1,2,2,3,3,4,5&gt;. You need to find out the two numbers which are repeated. Can you find the two numbers if you are told that you can only use constant-size extra storage?</li><li>Three coworkers are discussing salary issues in their company. They want to know whether the average salary of an employee in their company is greater than the industry average. They have found the industry average salary from a magazine survey. For the average salary in their company, they decide to take the average of their salaries (they assume that they are the only three employees in the company). However, they do not want to disclose their salaries. How can they take the average without disclosing their salaries?</li><li>You are travelling on a road and have reached a junction where two paths diverge. One path will take you to your correct destination. However you do not know which is the correct path, and alas, there are no sign boards! However, a truth teller and a liar are standing at the junction to help/confuse you. The truth-teller will always answer any question you ask truthfully. The liar will always answer any question you ask falsely. Now, you are allowed to ask only one question. You do not know who the truth-teller is and who the liar is. What is the single question you can ask to help you find the correct road to your  destination?</li><li>A permutation of length N is a one-to-one onto mapping p from 0, 1, 2,&#8230; -1 on to itself. A permutation can be applied to an array A of N integers. &#928;(A[i]) = A[&#928;(i)]. If you are allowed any amount of additional storage, how can you obtain the permutation of A given &#928;? If you are allowed to use only a constant amount of additional storage, how would your solution change?</li><li>We all know that the standard memory allocator function <code>malloc</code> is used for allocating memory in C programs. The size of the memory allocated in bytes is passed to <code>malloc</code> as a parameter. What would be the program behaviour if I pass zero as the parameter to <code>malloc</code>?</li><li>We are all familiar with signals such as <code>SIGSEGV</code>/<code>SIGBUS</code>, etc. I am a malicious user and I want to kill the programs of all users other than myself on the machine running Linux. Can I send a signal which will kill all other users&#8217; processes?</li><li>Can one use a floating-point constant value as an enumeration constant in C programs?</li><li>Remember that functions allocate storage on the stack to hold the activation records. You are asked to write a function which will return its stack size. How can you do this?</li><li>Here is a small code snippet:<pre class="brush: c; gutter: false; first-line: 1">int* foo(void* p)
{
        p = p + 3;
        return (int*)p;
}</pre><p>Can you identify any bug in the above code?</p><li>Let A be a sorted array of integers. You are given an integer K. Write a program to determine whether there are two indices i and j, such that A[i] + A[j] = K. Note that i and j need not be distinct.</li><li>Given two strings s and t, write a program to find all occurrences of t in s. You are originally told that s contains a maximum of 1,000 characters. Now, after having written your program to solve the problem, the examiner tells you that he was wrong, and s can contain 100,000 characters. Do you need to rewrite your algorithm to solve the problem?</li><li>You are given two strings, s and t. You need to determine whether t is a cyclic rotation of string s. For instance, string t is obtained by rotating each character of string s by k positions. For example, the string <em>kite</em> is a cyclic rotation of string <em>teki</em>. You are told that N is the maximum size of the string. Can you write a code to determine this in O(N) time with constant additional storage?</li><li>You are given a list of points in a two-dimensional Cartesian plane &lt;X1, Y1&gt;, &lt;X2.Y2&gt;.. &lt;Xn, Yn&gt;. You are asked to find the pair of points closest to each other in the Cartesian plane.</li><li>We typically use <code>malloc</code> and <code>free</code> to allocate/deallocate memory on the heap in C programs. However, in your case, you have been told that the dynamic memory has to be shared between two processes. Therefore, you need to do dynamic memory allocation on a shared memory segment, which can be shared between two processes. Can you write skeleton code to implement a dynamic memory allocator on a shared memory segment?</li><li>You are given a number N and asked to write a function to determine whether it is prime or not. Now that you have written the solution, you have been told to find that 10,000th prime number. Would it be more efficient to reuse your previous solution to solve this problem or would you create a new program to determine the 10,000th prime number? What is the runtime of your solution in either case?</li><li>You are given a stream of integers which come in as input. At any point of the input stream, you can be asked to determine the current maximum and the second largest number seen so far in the stream. Can you write a function to do this?</li></ol><h2>My &#8216;must-read book&#8217; for this month</h2><p>This month&#8217;s &#8220;must-read book&#8221; suggestion comes from one of our readers, Unnikrishnan, who recommends <em>Introduction to Algorithms: A Creative Approach</em> by Udi Manber. This book teaches you to examine each step in the algorithm design process and even takes you through the process of algorithm design by carefully crafted examples. Thank you, Unnikrishnan! I have not yet read the book but am hoping to do so in the coming months.</p><div class="note">If you have a favourite programming book or article that you think is a must-read for every programmer, please do send me a note with the book&#8217;s name, and a short write-up on why you think it is useful so that I can mention it in the column. This would help many readers who want to improve their coding skills.</p><p>If you have any favourite programming puzzles that you would like to discuss on this forum, please send them to me, along with your solutions and feedback, at sandyasm_AT_yahoo_DOT_com. Till we meet again next month, happy programming, and here&#8217;s wishing you the very best!</p></div><div>Feature image ourtesy: <a href="http://www.flickr.com/photos/the_sprouts/4981153823/">the.sprouts</a>. Reused under terms of CC-BY-NC-SA 2.0 License.</div><div id="crp_related"><h5>Related Posts:</h5><ul><li><a href="http://www.linuxforu.com/2011/01/codesport-4/" rel="bookmark" class="crp_title">CodeSport</a></li><li><a href="http://www.linuxforu.com/2011/04/codesport-april-2011/" rel="bookmark" class="crp_title">CodeSport (April 2011)</a></li><li><a href="http://www.linuxforu.com/2011/09/codesport-september-2011/" rel="bookmark" class="crp_title">CodeSport (September 2011)</a></li><li><a href="http://www.linuxforu.com/2011/12/codesport-december-2011/" rel="bookmark" class="crp_title">CodeSport (December 2011)</a></li><li><a href="http://www.linuxforu.com/2009/03/codesport-march-2009/" rel="bookmark" class="crp_title">CodeSport (March 2009)</a></li></ul></div>Tags: <a href="http://www.linuxforu.com/tag/cc/" title="C/C++" rel="tag">C/C++</a>, <a href="http://www.linuxforu.com/tag/codesport/" title="CodeSport" rel="tag">CodeSport</a>, <a href="http://www.linuxforu.com/tag/compiler-optimisation/" title="compiler optimisation" rel="tag">compiler optimisation</a>, <a href="http://www.linuxforu.com/tag/computer-science/" title="computer science" rel="tag">computer science</a>, <a href="http://www.linuxforu.com/tag/dynamic-memory-allocation/" title="Dynamic memory allocation" rel="tag">Dynamic memory allocation</a>, <a href="http://www.linuxforu.com/tag/even-integer/" title="even integer" rel="tag">even integer</a>, <a href="http://www.linuxforu.com/tag/integers/" title="integers" rel="tag">integers</a>, <a href="http://www.linuxforu.com/tag/interview-questions/" title="interview questions" rel="tag">interview questions</a>, <a href="http://www.linuxforu.com/tag/lfy-january-2012/" title="LFY January 2012" rel="tag">LFY January 2012</a>, <a href="http://www.linuxforu.com/tag/malloc/" title="malloc" rel="tag">malloc</a>, <a href="http://www.linuxforu.com/tag/memory-management/" title="memory management" rel="tag">memory management</a>, <a href="http://www.linuxforu.com/tag/odd-integers/" title="odd integers" rel="tag">odd integers</a>, <a href="http://www.linuxforu.com/tag/programming-questions/" title="programming questions" rel="tag">programming questions</a>, <a href="http://www.linuxforu.com/tag/puzzles/" title="puzzles" rel="tag">puzzles</a><br /> ]]></content:encoded> <wfw:commentRss>http://www.linuxforu.com/2012/01/codesport-january-2012/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Joy of Programming: Understanding Bit-fields in C</title><link>http://www.linuxforu.com/2012/01/joy-of-programming-understanding-bit-fields-c/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=joy-of-programming-understanding-bit-fields-c</link> <comments>http://www.linuxforu.com/2012/01/joy-of-programming-understanding-bit-fields-c/#comments</comments> <pubDate>Mon, 30 Jan 2012 05:21:43 +0000</pubDate> <dc:creator>S.G. Ganesh</dc:creator> <category><![CDATA[Coding]]></category> <category><![CDATA[Columns]]></category> <category><![CDATA[bit-fields]]></category> <category><![CDATA[C]]></category> <category><![CDATA[c structure]]></category> <category><![CDATA[exponent]]></category> <category><![CDATA[floating point]]></category> <category><![CDATA[Joy of Programming]]></category> <category><![CDATA[LFY January 2012]]></category> <category><![CDATA[printf]]></category> <category><![CDATA[unsigned int]]></category> <category><![CDATA[unsigned value]]></category> <category><![CDATA[value ranges]]></category><guid isPermaLink="false">http://www.linuxforu.com/?p=9348</guid> <description><![CDATA[One important feature that distinguishes C as a systems programming language is its support for bit-fields. Let us explore this feature in this column. In C, structure members can be specified with size...]]></description> <content:encoded><![CDATA[<p><img class="alignright size-full wp-image-9350" title="Bit-fields" src="http://cdn.linuxforu.com/wp-content/uploads/2012/01/bits.jpg?d9c344" alt="Bit-fields" width="300" height="300" /></p><div class="introduction">One important feature that distinguishes C as a systems programming language is its support for bit-fields. Let us explore this feature in this column.</div><p>In C, structure members can be specified with size in number of bits, and this feature is known as bit-fields. Bit-fields are important for low-level (i.e., for systems programming) tasks such as directly accessing systems resources, processing, reading and writing in terms of streams of bits (such as processing packets in network programming), cryptography (encoding or decoding data with complex bit-manipulation), etc.</p><p>Consider the example of reading the components of a floating-point number. A 4-byte floating-point number in the IEEE 754 standard consists of the following:</p><ul><li>The first bit is reserved for the sign bit &#8212; it is 1 if the number is negative and 0 if it is positive.</li><li>The next 8 bits are used to store the exponent in the unsigned form. When treated as a signed exponent, this exponent value ranges from -127 to +128. When treated as an unsigned value, its value ranges from 0 to 255.</li><li>The remaining 23 bits are used to store the mantissa.</li></ul><p>Here is a program to print the value of a floating-point number into its constituents:</p><pre class="brush: c; gutter: false; first-line: 1">struct FP {
// the order of the members depends on the
// endian scheme of the underlying machine
      unsigned int mantissa : 23;
     unsigned int exponent : 8;
      unsigned int sign : 1;
} *fp;

int main() {
       float f = -1.0f;
       fp = (struct FP *)&amp;f;

printf(&quot; sign = %s, biased exponent = %u,
mantissa = %u &quot;, fp-&gt;sign ? &quot;negative&quot; : &quot;positive&quot;,
fp-&gt;exponent, fp-&gt;mantissa);
}</pre><p>For the floating-point number -1.0, this program prints:</p><pre class="brush: c; gutter: false; first-line: 1">sign = negative, biased exponent = 127, mantissa = 0</pre><p>Since the sign of the floating-point number is negative, the value of the sign bit is 1. Since the exponent is actual 0, in unsigned exponent format, it is represented as 127, and hence that value is printed. The mantissa in this case is 0, and hence it is printed as it is.</p><p>To understand how floating-point arithmetic works, see this <a href="http://en.wikipedia.org/wiki/Single_precision">Wikipedia article</a>.</p><p>An alternative to using bit-fields is to use integers directly, and manipulate them using bitwise operators (such as <code>&amp;</code>, <code>|</code>, <code>~</code>, etc.). In the case of reading the components of a floating-point number, we could use bitwise operations also. However, in many cases, such manipulation is a round-about way to achieve what we need, and the solution using bit-fields provides a more direct solution and hence is a useful feature.</p><p>There are numerous limitations in using bit-fields. For example, you cannot apply operators such as <code>&amp; (addressof)</code>, <code>sizeof</code> to bit-fields. This is because these operators operate in terms of bytes (not bits) and the bit-fields operate in terms of bits (not bytes), so you cannot use these operators. In other words, an expression such as <code>sizeof(fp-&gt;sign)</code> will result in a compiler error.</p><p>Another reason is that the underlying machine supports addressing in terms of bytes, and not bits, and hence such operators are not feasible. Then how does it work when expressions such as <code>fp-&gt;sign</code>, or <code>fp-&gt;exponent</code> are used in this program?</p><p>Note that C allows only integral types as bit-fields, and hence expressions referring to the bit-fields are converted to integers. In this program, as you can observe, we used the <code>%u</code> format specifier, which is for an unsigned integer &#8212; the bit-field value was converted into an integer and that is why the program worked.</p><p>Those new to bit-fields face numerous surprises when they try using them. This is because a lot of low-level details come into the picture while using them. In the programming example for bit-fields, you might have noticed the reversal in the order of the sign, exponent and mantissa, which is because of the underlying endian scheme followed. Endian refers to how bytes are stored in memory (see this <a href="http://en.wikipedia.org/wiki/Endianness">Wikipedia article</a> for more details).</p><p>Can you explain the following simple program that makes use of a bit-field?</p><pre class="brush: c; gutter: false; first-line: 1">struct bitfield {
    int bit : 1;
} BIT;
int main() {
   BIT.bit = 1;
   printf(&quot; sizeof BIT is = %d\n&quot;, sizeof(BIT));
   printf(&quot; value of bit is = %d &quot;, BIT.bit);

}</pre><p>It prints:</p><pre class="brush: text; gutter: false; first-line: 1"> sizeof BIT is = 4
 value of bit is = -1</pre><p>Why? Note that it is not a compiler error to attempt to find the <code>sizeof(BIT)</code> because it is a structure; had we attempted <code>sizeof(BIT.bit)</code>, that will not compile.</p><p>Now, coming to the output, if we had used only one bit in the <code>BIT</code> structure, why is the <code>sizeof(BIT)</code> 4 bytes? It is because of the addressing requirement of the underlying machine. The machine might perhaps require all structs to start in an address divisible by 4; or perhaps, allocating the size of a WORD for the structure is more efficient even if the underlying machine may require that structs start at an even address. Also, the compiler is free to add extra bits between any struct members (including bit-field members), which is known as &#8220;padding&#8221;.</p><p>Now let us come to the next output. We set <code>BIT.bit = 1</code>; and the <code>printf</code> statement printed <code>-1</code>! Why was that?</p><p>Note that we declared bit as <code>int bit : 1</code>; where the compiler treated the bit to be a signed integer of one bit size. Now, what is the range of a 1-bit signed integer?</p><p>It is from 0 to -1 (not 0 and 1, which is a common mistake). Remember the formula for finding out the range of signed integers: 2<sup>(n-1)</sup> to 2<sup>(n-1)</sup>-1 where <em>N</em> is the number of bits. For example, if <em>N</em> is 8 (number of bits in a byte), i.e., the range of a signed integer of size 8 is -2<sup>(8-1)</sup> to 2<sup>(8-1)</sup>-1, which is -128 to +127. Now, when <em>N</em> is 1, i.e., the range of a signed integer of size 1, it is -2<sup>(1-1)</sup> to 2<sup>(1-1)</sup>-1, which is -1 to 0!</p><p>No doubt, bit-fields are a powerful feature for low-level bit-manipulation. The cost of using bit-fields is the loss of portability. We already saw how padding and ending issues can affect portability in our simple program for reading the components of a floating-point number. Bit-fields should be used in places where space is very limited, and when functionality is demanding. Also, the gain in space could be lost in efficiency: bit-fields take more time to process, since the compiler takes care of (and hides) the underlying complexity in bit-manipulation to get/set the required data. Bugs associated with bit-fields can be notoriously hard to debug, since we need to understand data in terms of bits. So, use bit-fields sparingly and with care.</p><div class="imagecredit">Feature image courtesy: <a href="http://www.flickr.com/photos/therefore/100678177/">Dean Terry</a>. Reused under the terms of CC-BY-NC-ND 2.0 License.</div><div id="crp_related"><h5>Related Posts:</h5><ul><li><a href="http://www.linuxforu.com/2009/03/joy-of-programming-how-to-detect-integer-overflow/" rel="bookmark" class="crp_title">Joy of Programming: How to Detect Integer Overflow</a></li><li><a href="http://www.linuxforu.com/2009/02/joy-of-programming-about-the-java-overflow-bug/" rel="bookmark" class="crp_title">Joy of Programming: About the Java Overflow Bug</a></li><li><a href="http://www.linuxforu.com/2009/01/joy-of-programming-some-puzzling-things-about-c/" rel="bookmark" class="crp_title">Joy of Programming: Some Puzzling Things About C Language!</a></li><li><a href="http://www.linuxforu.com/2012/01/device-drivers-partitions-hard-disk/" rel="bookmark" class="crp_title">Device Drivers, Part 14: A Dive Inside the Hard Disk for Understanding Partitions</a></li><li><a href="http://www.linuxforu.com/2011/01/the-joy-of-programming%e2%80%94penny-wise-and-pound-foolish/" rel="bookmark" class="crp_title">The Joy of Programming—Penny wise and pound foolish!</a></li></ul></div>Tags: <a href="http://www.linuxforu.com/tag/bit-fields/" title="bit-fields" rel="tag">bit-fields</a>, <a href="http://www.linuxforu.com/tag/c/" title="C" rel="tag">C</a>, <a href="http://www.linuxforu.com/tag/c-structure/" title="c structure" rel="tag">c structure</a>, <a href="http://www.linuxforu.com/tag/exponent/" title="exponent" rel="tag">exponent</a>, <a href="http://www.linuxforu.com/tag/floating-point/" title="floating point" rel="tag">floating point</a>, <a href="http://www.linuxforu.com/tag/joy-of-programming/" title="Joy of Programming" rel="tag">Joy of Programming</a>, <a href="http://www.linuxforu.com/tag/lfy-january-2012/" title="LFY January 2012" rel="tag">LFY January 2012</a>, <a href="http://www.linuxforu.com/tag/printf/" title="printf" rel="tag">printf</a>, <a href="http://www.linuxforu.com/tag/unsigned-int/" title="unsigned int" rel="tag">unsigned int</a>, <a href="http://www.linuxforu.com/tag/unsigned-value/" title="unsigned value" rel="tag">unsigned value</a>, <a href="http://www.linuxforu.com/tag/value-ranges/" title="value ranges" rel="tag">value ranges</a><br /> ]]></content:encoded> <wfw:commentRss>http://www.linuxforu.com/2012/01/joy-of-programming-understanding-bit-fields-c/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Lisp: Tears of Joy, Part 7</title><link>http://www.linuxforu.com/2011/12/lisp-tears-of-joy-part-7/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lisp-tears-of-joy-part-7</link> <comments>http://www.linuxforu.com/2011/12/lisp-tears-of-joy-part-7/#comments</comments> <pubDate>Fri, 30 Dec 2011 10:37:37 +0000</pubDate> <dc:creator>Vivek Shangari</dc:creator> <category><![CDATA[Coding]]></category> <category><![CDATA[Developers]]></category> <category><![CDATA[AREF]]></category> <category><![CDATA[CLOS]]></category> <category><![CDATA[Common Lisp]]></category> <category><![CDATA[Languages]]></category> <category><![CDATA[LFY December 2011]]></category> <category><![CDATA[Lisp]]></category> <category><![CDATA[lisp code]]></category> <category><![CDATA[lisp programs]]></category> <category><![CDATA[Lisp: Tears of Joy series]]></category> <category><![CDATA[macro definition]]></category> <category><![CDATA[Macros]]></category> <category><![CDATA[object-based systems]]></category> <category><![CDATA[Paul Graham]]></category> <category><![CDATA[programming]]></category> <category><![CDATA[syntax]]></category><guid isPermaLink="false">http://www.linuxforu.com/?p=8580</guid> <description><![CDATA[Lisp has been hailed as the world&#8217;s most powerful programming language. But only the top percentile of programmers use it because of its cryptic syntax and academic reputation. This is rather unfortunate, since...]]></description> <content:encoded><![CDATA[<p><img class="aligncenter size-large wp-image-8581" title="Time to Lisp" src="http://cdn.linuxforu.com/wp-content/uploads/2011/12/Open-Image-LISP-7-590x391.jpg?d9c344" alt="Time to Lisp" width="590" height="391" /></p><div class="introduction">Lisp has been hailed as the world&#8217;s most powerful programming language. But only the top percentile of programmers use it because of its cryptic syntax and academic reputation. This is rather unfortunate, since Lisp isn&#8217;t that hard to grasp. If you want to be among the crème de la crème, <a href="http://www.linuxforu.com/tag/lisp-tears-of-joy-series/">this series</a> is for you. This is the seventh article in the series, which began in <a title="Lisp: Tears of Joy, Part 1" href="http://www.linuxforu.com/2011/06/lisp-tears-of-joy-part-1/">June 2011</a>.</div><h2>Macros &#8212; can&#8217;t get enough of them!</h2><p>You already know from my <a href="http://www.linuxforu.com/tag/lisp-tears-of-joy-series/">previous articles</a> that macros are Lisp programs that generate other Lisp programs. The generated Lisp code has fully parenthesised notation, and so does the macro that generates the code. In the simplest case, a macro substitutes forms within a template, clearly establishing a visual correspondence between the generating code and the generated code.</p><p>Complex macros can use the full power of the Lisp language to generate code according to the macro parameters; often, a template form is wrapped in code that constructs appropriate sub-forms, but even this approach is just a typical pattern of use, and not a requirement (or restriction) of the Lisp macro facility.</p><p>To refresh our memories, let&#8217;s examine the mechanism by which the Lisp system translates code generated by a macro. You define a macro with a <code>defmacro</code> form; <code>defmacro</code> is like <code>defun</code>, but instead of returning values, the body of the <code>defmacro</code> returns a Lisp form. Your program &#8216;calls&#8217; a macro the same way it calls a function, but the behaviour is quite different.</p><p>First, none of the macro&#8217;s parameters are evaluatedever. Macro parameters are bound literally to the corresponding arguments in the macro definition. If you pass <code>(* 7 (+ 3 2))</code> to a macro, the argument in the body of the macro definition is bound to the literal list <code>(* 7 (+ 3 2))</code> and not the value 35.</p><p>Next, the macro expander is invoked, receiving all of the actual parameters bound to their corresponding arguments as named by the <code>defmacro</code> form. The macro expander is merely the body of the <code>defmacro</code> form, which is just Lisp code; the only catch is that the Lisp system expects the macro expander to return a Lisp form. The Lisp system then evaluates whatever form the macro expander returns.</p><p>A Lisp implementation may expand macros at different times. A macro could be expanded just once, when your program is compiled. Or it could be expanded on first use as your program runs, and the expansion could be cached for subsequent reuse. A properly written macro will behave the same under all of these implementations.</p><p>Let&#8217;s explore a real-world example of using a macro to extend Lisp into the problem domain. In addition to providing a macro expander, our new macro will automatically generate an environment that will be referenced by the expander. Our example will show how to move computations from run-time to compile-time, and how to share information computed at compile-time.</p><p>Let&#8217;s say you&#8217;re working on an interactive game that makes heavy use of the trigonometric function sin r in computing player motion and interaction. You&#8217;ve already determined that calling the Lisp function sin is too time-consuming; you also know that your program will work just fine with approximate results for the computation of sin r. You&#8217;d like to define a lookup-sin macro to do the table lookup at runtime and also hide the details of table generation, which would just clutter your program&#8217;s source code.</p><p>Your macro will be invoked as (lookup-sin radians divisions), where radians is always in the range of zero to one-half pi, and divisions is the number of discrete values available as the result of lookup-sin. At runtime, the macro expander will just compute the index into a lookup table, and return the value from the table. The table will be generated at compile-time (on most Lisp systems). Furthermore, only one table will ever be generated for a given value of divisions in the macro call.</p><pre class="brush: text; gutter: false; first-line: 1">;; This is where we cache all of the sine tables generated during compilation.
;; The tables stay around at runtime so they can be used for lookups.
(defvar *sin-tables* (make-hash-table)
    &quot;A has table of tables of sine values. The hash is keyed by the number of entries in each sine table.&quot;)

;; This is a helper function for the lookup-sin macro. It is used only at compile
;; time.
(defun get-sin-table-and-increment (divisions)
    &quot;Returns a sine lookup table and the number of radians quantised by each entry in the table. Tables of a given size are reused. A table covers angles from zero to pi/2 radians.&quot;
(let ((table (gethash divisions *sin-tables* :none))
      (increment (/ pi 2 divisions)))
    (when (eq table :none)
        ;; Uncomment the next line to see when a table gets created.

        ;; (print `|Making new table|)
        (setq table
            (setf (gethash divisions *sin-tables*)
                  (make-array
                    (1+ divisions)
                    :initial-element 1.0)))
        (dotimes (i divisions)
            (setf (aref table i)
                  (sin (* increment i)))))
     (values table increment)))

;; Macro calls the helper at compile time, and returns an AREF form to do the
;; lookup at runtime.
(defmacro lookup-sin (radians divisions)
    &quot;Return a sine value via table lookup.&quot;
    (multiple-value-bind (table increment)
                         (get-sin-table-and-increment divisions)
        `(aref, table (round, radians, increment))))</pre><p>Let us examine what is happening here. When this program runs, it executes just <code>aref</code>  (and associated round) to look up the sin r value.</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (pprint (macroexpand-1 `(lookup-sin (/ pi 4) 50)))

(AREF #(0.0D0 0.03141075907812829D0 0.06279051952931338D0 0.09410831331851433D0 0.12533323356430426D0 0.15643446504023087D0 0.18738131458572463D0 0.21814324139654257D0 0.2486898871648548D0 0.2789911060392293D0
        0.3090169943749474D0 0.3387379202452914D0 0.368124552684678D0 0.3971478906347806D0 0.4257792915650727D0 0.4539904997395468D0 0.4817536741017153D0 0.5090414157503713D0 0.5358267949789967D0 0.5620833778521306D0
        0.5877852522924731D0 0.6129070536529765D0 0.6374239897486898D0 0.6613118653236518D0 0.6845471059286887D0 0.7071067811865476D0 0.7289686274214116D0 0.7501110696304596D0 0.7705132427757893D0 0.7901550123756904D0
        0.8090169943749475D0 0.8270805742745618D0 0.8443279255020151D0 0.8607420270039436D0 0.8763066800438637D0 0.8910065241883678D0 0.9048270524660196D0 0.9177546256839811D0 0.9297764858882515D0 0.9408807689542256D0
        ...)
      (ROUND (/ PI 4) 0.031415926535897934D0))</pre><p>Note that the macro call makes no mention of a lookup table. Tables are generated as needed by (and for) the compiler.</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (lookup-sin (/ pi 4) 50)
0.7071067811865476D0</pre><p>In the macro expansion, the <code>#(...)</code> is the printed representation of the lookup table for 50 divisions of the quarter circle. This table is stored in the <code>*sin-tables*</code> hash table, where it is shared by every macro call to <code>(lookup-sin angle 50)</code>. We don&#8217;t even have to do a hash lookup at runtime, because the macro expander has captured the free variable table from the multiple-value-bind form in <code>lookup-sin</code>.</p><h2>Macros that define macros</h2><p>Macros that define macros are used infrequently, partly because it&#8217;s hard to think of a good use for this technique, and partly because it&#8217;s difficult to get right. The following macro, based on an example in Paul Graham&#8217;s book <em>On Lisp</em>, can be used to define synonyms for the names of Lisp functions, macros, and special forms.</p><pre class="brush: text; gutter: false; first-line: 1">&gt; (defmacro defsynonym (old-name new name)
&quot;Define OLD-NAME to be equivalent to NEW-NAME when used in the first position of a Lisp form.&quot;
 `(defmacro, new-name (&amp;rest args)
                    `(,`,old-name, @args)))
DEFSYNONYM

&gt; (defsynonym make-pair cons)
MAKE-PAIR

&gt; (make-pair `a `b)
(A . B)</pre><p>Macros are always a little bit dangerous because code containing a macro call does not automatically get updated if you change the definition of the macro. You can always establish your own convention to help you remember that you need to recompile certain code after you change a macro definition. But there&#8217;s always the possibility that you&#8217;ll forget, or make a mistake.</p><p>Ultimately, the likelihood that you&#8217;ll inadvertently end up with code that was compiled with an old version of a macro is directly proportional to how often you&#8217;re likely to change the macro. A macro like <code>defsynonym</code> practically begs to be used again and again as you generate new code. If you change your mind about the old name to associate with a given new name, all of your previously compiled code will still refer to the old name that you had decided upon earlier.</p><p>I&#8217;ll leave you here to have fun with your macros.</p><p>In the next article, we&#8217;ll take a peek into Common Lisp Object System (CLOS) which allows you to build very sophisticated object-based systems. If you care to code with a strongly object-oriented mindset, you will probably find all the OOP language functionality you need in Common Lisp. CLOS has many advanced object-oriented features that you won&#8217;t find in many other places. Because of this, CLOS has often been used as a research tool for studying OOP ideas.<div id="crp_related"><h5>Related Posts:</h5><ul><li><a href="http://www.linuxforu.com/2011/10/lisp-tears-of-joy-part-5/" rel="bookmark" class="crp_title">Lisp: Tears of Joy, Part 5</a></li><li><a href="http://www.linuxforu.com/2011/11/lisp-tears-of-joy-part-6/" rel="bookmark" class="crp_title">Lisp: Tears of Joy, Part 6</a></li><li><a href="http://www.linuxforu.com/2011/08/lisp-tears-of-joy-part-3/" rel="bookmark" class="crp_title">Lisp: Tears of Joy, Part 3</a></li><li><a href="http://www.linuxforu.com/2012/01/lisp-tears-of-joy-part-8/" rel="bookmark" class="crp_title">Lisp: Tears of Joy, Part 8</a></li><li><a href="http://www.linuxforu.com/2011/09/lisp-tears-of-joy-part-4/" rel="bookmark" class="crp_title">Lisp: Tears of Joy, Part 4</a></li></ul></div>Tags: <a href="http://www.linuxforu.com/tag/aref/" title="AREF" rel="tag">AREF</a>, <a href="http://www.linuxforu.com/tag/clos/" title="CLOS" rel="tag">CLOS</a>, <a href="http://www.linuxforu.com/tag/common-lisp/" title="Common Lisp" rel="tag">Common Lisp</a>, <a href="http://www.linuxforu.com/tag/languages/" title="Languages" rel="tag">Languages</a>, <a href="http://www.linuxforu.com/tag/lfy-december-2011/" title="LFY December 2011" rel="tag">LFY December 2011</a>, <a href="http://www.linuxforu.com/tag/lisp/" title="Lisp" rel="tag">Lisp</a>, <a href="http://www.linuxforu.com/tag/lisp-code/" title="lisp code" rel="tag">lisp code</a>, <a href="http://www.linuxforu.com/tag/lisp-programs/" title="lisp programs" rel="tag">lisp programs</a>, <a href="http://www.linuxforu.com/tag/lisp-tears-of-joy-series/" title="Lisp: Tears of Joy series" rel="tag">Lisp: Tears of Joy series</a>, <a href="http://www.linuxforu.com/tag/macro-definition/" title="macro definition" rel="tag">macro definition</a>, <a href="http://www.linuxforu.com/tag/macros/" title="Macros" rel="tag">Macros</a>, <a href="http://www.linuxforu.com/tag/object-based-systems/" title="object-based systems" rel="tag">object-based systems</a>, <a href="http://www.linuxforu.com/tag/paul-graham/" title="Paul Graham" rel="tag">Paul Graham</a>, <a href="http://www.linuxforu.com/tag/programming/" title="programming" rel="tag">programming</a>, <a href="http://www.linuxforu.com/tag/syntax/" title="syntax" rel="tag">syntax</a><br /> ]]></content:encoded> <wfw:commentRss>http://www.linuxforu.com/2011/12/lisp-tears-of-joy-part-7/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>CodeIgniter: Form APIs, Validations &amp; Pagination Techniques</title><link>http://www.linuxforu.com/2011/12/codeigniter-form-apis-validations-pagination-techniques/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=codeigniter-form-apis-validations-pagination-techniques</link> <comments>http://www.linuxforu.com/2011/12/codeigniter-form-apis-validations-pagination-techniques/#comments</comments> <pubDate>Fri, 30 Dec 2011 07:23:37 +0000</pubDate> <dc:creator>Ankur Aggarwal</dc:creator> <category><![CDATA[Coding]]></category> <category><![CDATA[Developers]]></category> <category><![CDATA[application models]]></category> <category><![CDATA[CodeIgniter]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[database table]]></category> <category><![CDATA[file uploads]]></category> <category><![CDATA[form validation]]></category> <category><![CDATA[forms]]></category> <category><![CDATA[hello world]]></category> <category><![CDATA[html]]></category> <category><![CDATA[input type text]]></category> <category><![CDATA[LFY December 2011]]></category> <category><![CDATA[Login]]></category> <category><![CDATA[pagination]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[table border]]></category> <category><![CDATA[validation rules]]></category> <category><![CDATA[validations]]></category> <category><![CDATA[Web]]></category> <category><![CDATA[web programming]]></category><guid isPermaLink="false">http://www.linuxforu.com/?p=8565</guid> <description><![CDATA[In the previous article on CodeIgniter, we discussed the concept of the MVC structure used in CodeIgniter, did a &#8220;Hello world&#8221; program, and a simple program with database connectivity. Now, let&#8217;s take a...]]></description> <content:encoded><![CDATA[<p><img class="alignright size-full wp-image-8571" title="Form builders" src="http://cdn.linuxforu.com/wp-content/uploads/2011/12/CodeIgniter2.jpg?d9c344" alt="Form builders" width="350" height="251" /></p><div class="introduction">In the <a title="Let's Play with CodeIgniter" href="http://www.linuxforu.com/2011/10/lets-play-with-codeigniter/">previous article on CodeIgniter</a>, we discussed the concept of the MVC structure used in CodeIgniter, did a &#8220;Hello world&#8221; program, and a simple program with database connectivity. Now, let&#8217;s take a look at different form APIs, built-in validations, and pagination techniques.</div><h2>Form APIs</h2><p>Well, to use form APIs, you must include the &#8220;form&#8221; in the autoload helpers in your <code>autoload.php</code> configuration file, such as: <code>$autoload['helper'] = array('url','form');</code></p><div class="note"><strong>Note:</strong> You always need to include helpers in the autoload file to access their APIs. For example: If you want to include file uploads in your application, you must include &#8220;file&#8221; in autoload helper.</div><p>Let&#8217;s create a simple login form, and add form validation rules. We created the <code>lfy_users</code> database table with the username and password columns (refer to <a title="Let's Play with CodeIgniter" href="http://www.linuxforu.com/2011/10/lets-play-with-codeigniter/">previous article</a>). I manually added an entry; you can also do this by creating a separate form. Our form is simple to look at; you can add CSS if you want. There will be three files in the MVC structure:</p><ol><li>Controller File: <code>login.php</code> (<code>/var/www/ci2/application/controllers/login.php</code>)</li><li>View File: <code>loginview.php</code> (<code>/var/www/ci2/application/views/loginview.php</code>)</li><li>Model File: <code>loginmodel.php</code> (<code>/var/www/ci2/application/models/loginmodel.php</code>)</li></ol><h3>The loginview.php file</h3><pre class="brush: html; gutter: true; first-line: 1">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Login View &lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php echo form_open(&#039;login/check&#039;); ?&gt;
&lt;table border=&#039;0&#039;&gt;
  &lt;tr align=&#039;center&#039;&gt;
  &lt;td colspan=&#039;2&#039;&gt;&lt;b&gt;Welcome To Linux For You&lt;/b&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;User Name: &lt;/td&gt;
  &lt;td&gt;&lt;input type=&#039;text&#039; name=&#039;username&#039; id=&#039;username&#039; /&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Password: &lt;/td&gt;
    &lt;td&gt;&lt;input type=&#039;password&#039; name=&#039;password&#039; id=&#039;password&#039; /&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td colspan=&#039;2&#039; align=&#039;center&#039; style=&#039;padding-left:40px&#039;&gt;&lt;?php echo form_submit(&#039;submit&#039;,&#039;Submit&#039;) ?&gt;
     &lt;input type=&#039;button&#039; value=Cancel onClick=&#039;window.location.reload();&#039;/&gt;&lt;/td&gt;
 &lt;/tr&gt;
&lt;/table&gt;
&lt;?php echo form_close()?&gt;
&lt;?php echo validation_errors(); ?&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><p>The above code, when simply loaded in the controller file, will give a browser output somewhat like what&#8217;s shown in Figure 1.</p><div id="attachment_8572" class="wp-caption aligncenter" style="width: 590px"><a href="http://cdn.linuxforu.com/wp-content/uploads/2011/12/image1.png?d9c344"><img class="wp-image-8572 " title="A simple login page" src="http://cdn.linuxforu.com/wp-content/uploads/2011/12/image1-590x314.png?d9c344" alt="A simple login page" width="590" height="314" /></a><p class="wp-caption-text">Figure 1: A simple login page</p></div><p>Here&#8217;s the explanation:</p><ol><li><code>form_open('functionname')</code> will create a form with the POST method by default. On submission, it will send the form data to the specified function (here, the check function of the controller file).</li><li><code>form_submit('submit','Submit)</code> will create and perform the submit button action. Arguments passed are <code>type</code> and <code>value</code>.</li><li><code>close()</code> marks the end of the form.</li><li><code>validation_errors()</code> will print all validation errors set in the controller file.</li><li>On cancellation, it will simply reload the page.</li></ol><h3>File login.php</h3><pre class="brush: php; gutter: true; first-line: 1">&lt;?php
class Login extends CI_Controller {
function index()
{
$this-&gt;load-&gt;model(&#039;loginmodel&#039;);
$this-&gt;load-&gt;view(&#039;loginview&#039;);
}
function check()
{
$this-&gt;load-&gt;library(&#039;form_validation&#039;);   #1
$this-&gt;form_validation-&gt;set_rules(&#039;username&#039;,&#039;User Name&#039;,&#039;trim|required&#039;); #2
$this-&gt;form_validation-&gt;set_rules(&#039;password&#039;,&#039;Password&#039;,&#039;trim|required&#039;);
if($this-&gt;form_validation-&gt;run()==FALSE)    #3
{
$this-&gt;load-&gt;view(&#039;loginview&#039;);
}

$this-&gt;load-&gt;model(&#039;loginmodel&#039;);
$userName=$this-&gt;input-&gt;post(&#039;username&#039;); #4
$password=$this-&gt;input-&gt;post(&#039;password&#039;);
$userCount=$this-&gt;loginmodel-&gt;check($userName,$password); #5

if($userCount[0][&#039;count&#039;]&gt;0)
{
echo &quot;Login Successful&quot;;
}
else if ($userCount[0][&#039;count&#039;]==0)
{
echo &quot;Wrong User Name / Password&quot;;
}
}// end of funcion check
} //end of class
?&gt;</pre><p>And the explanation for this is as follows:</p><ol><li>We loaded the <code>form_validation</code> library manually, to use the built-in validation functions.</li><li>We set the rules for our data fields. Arguments passed are the field name, error message and validation rules, respectively; the most important is the last one. The <code>required</code> rule makes that field compulsory. You can set multiple rules for a single field using a <code>|</code> operator between them. For example, to specify that a valid email address is required, use <code>required|valid_email</code>. Explore more built-in validation rules in the documentation of <code>form_validation</code>.</li><li>In case form validation fails, the page will simply get reloaded.</li><li>As explained in the view file source, the form will throw its data to the check function of the controller file. To access that data, use the built-in <code>$this-&gt;input-&gt;post('fieldname')</code> API of the form helper. Here, they are stored in different variables.</li><li>Next, control will move to the model file, and it will check for the entered username and password in the database. If the count returns more than one, the username and password is correct, and &#8220;Login Successful&#8221; will be displayed, else &#8220;Wrong user name/password&#8221;.</li></ol><p>Submitting a form with blank fields yields validation errors, like those in Figure 2.</p><div id="attachment_8573" class="wp-caption aligncenter" style="width: 590px"><a href="http://cdn.linuxforu.com/wp-content/uploads/2011/12/image2.png?d9c344"><img class="size-large wp-image-8573 " title="Validation check" src="http://cdn.linuxforu.com/wp-content/uploads/2011/12/image2-590x358.png?d9c344" alt="Validation check" width="590" height="358" /></a><p class="wp-caption-text">Figure 2: Validation check</p></div><h3>File loginmodel.php</h3><pre class="brush: php; gutter: true; first-line: 1">&lt;?php
class LoginModel extends CI_Model {
function check($userName,$password)
{
$query=&quot;select count(&#039;userName&#039;) as count from lfy_users where userName=&#039;$userName&#039; and password=&#039;$password&#039;&quot;;
$result=$this-&gt;db-&gt;query($query);
return $result-&gt;result_array();
}
}
?&gt;</pre><p>The <code>check()</code> function will check for the user name and password in the database, as described above.</p><div class="note"><strong>Note:</strong> I have used a simple varchar password field in this example, to keep things simple. You should encrypt the password before storing, using MD5, SHA1 types.</div><h2>Pagination</h2><p>Display grids are the simplest way of representing data. But what if there are thousands of records? We use a pagination technique to display a certain amount of records on every page. The built-in CodeIgniter pagination APIs make this quite easy. Here&#8217;s an example displaying data of seven users, paginating to two records per page (<code>/var/www/ci2/application/controllers/displaycontroller.php</code>).</p><h3>File displaycontroller.php</h3><pre class="brush: php; gutter: true; first-line: 1">&lt;?php
class DisplayController extends CI_Controller {
function display($offset=0)
{
$limit=2;             #1
$this-&gt;load-&gt;model(&#039;displaymodel&#039;);
$result[&#039;contents&#039;]=$this-&gt;displaymodel-&gt;getRows($limit,$offset);
$result[&#039;numOfRows&#039;]=$this-&gt;displaymodel-&gt;countRows();
    $this-&gt;load-&gt;library(&#039;pagination&#039;); #2
    $this-&gt;load-&gt;library(&#039;table&#039;);
    $config=array(
        &#039;base_url&#039;=&gt;&#039;http://localhost/ci2/index.php/displaycontroller/display&#039;,
        &#039;total_rows&#039;=&gt; $result[&#039;numOfRows&#039;][0][&#039;count&#039;],
        &#039;per_page&#039;=&gt;$limit,
        &#039;num_links&#039;=&gt;2
        );                   #3
    $this-&gt;pagination-&gt;initialize($config);     #4
    $result[&#039;pagination&#039;]=$this-&gt;pagination-&gt;create_links();  #5
$this-&gt;load-&gt;view(&#039;displayview&#039;,$result);
}
}
?&gt;</pre><p>Here&#8217;s the explanation:</p><ol><li>The idea is to fetch the records according to the limit set (this will also be <code>record_per_page</code>) and set the offset value in the URI segment. The initial offset value is 0.</li><li>We loaded the pagination library.</li><li>Pagination demands certain parameters to be initialised &#8212; we have created an array of such parameters. <code>base_url</code> is the link to which the page is to be reloaded after getting a hit on any page number; <code>total_rows</code> refers to the total records; <code>per_page</code> is the limit of records to show on one page; <code>num_links</code> is the maximum links allowed for display (after that, &#8220;First&#8221; and &#8220;Last&#8221; will appear).</li><li>We initialised pagination with the above parameters.</li><li>We fetched the created links into the pagination variable.</li></ol><p>You will see something like what is shown in Figure 3 after completing the whole program.</p><div id="attachment_8574" class="wp-caption aligncenter" style="width: 585px"><img class="size-full wp-image-8574" title="Pagination" src="http://cdn.linuxforu.com/wp-content/uploads/2011/12/image3.png?d9c344" alt="Pagination" width="585" height="256" /><p class="wp-caption-text">Figure 3: Pagination</p></div><p>Notice the offset value (4 in the URI); it increments by 2 (<code>record_per_page</code>) on each page forward, and decreases by 2, going backwards.</p><h3>File displayview.php</h3><pre class="brush: html; gutter: true; first-line: 1">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Display Grid Through Code Igniter&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
Records Found: &lt;?php echo $numOfRows[0][&#039;count&#039;]; ?&gt;
&lt;br&gt;&lt;br&gt;
&lt;table border=1&gt;
&lt;tr&gt;
&lt;td&gt;S.No &lt;/td&gt;
&lt;td&gt;User Name&lt;/td&gt;
&lt;td&gt;Password&lt;/td&gt;
&lt;/tr&gt;
&lt;?php foreach($contents as $users) { ?&gt;
&lt;tr&gt;
&lt;td&gt;&lt;?php echo $users[&#039;userId&#039;]; ?&gt;
&lt;td&gt;&lt;?php echo $users[&#039;userName&#039;];?&gt;&lt;/td&gt;
&lt;td&gt;&lt;?php echo $users[&#039;password&#039;];?&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;?php } ?&gt;
&lt;/table&gt;
&lt;?php if(strlen($pagination)) { ?&gt;
Pages: &lt;?php echo $pagination; }?&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><p>The view file is quite simple. We can add pagination at the end, if it exists. You can apply CSS according to your needs.</p><h3>File displaymodel.php</h3><pre class="brush: php; gutter: true; first-line: 1">&lt;?php
class DisplayModel extends CI_Model{
function getRows($limit,$offset)
{
$query=$this-&gt;db-&gt;select(&#039;userId,userName,password&#039;)
       -&gt;from(&#039;lfy_users&#039;)
       -&gt;limit($limit,$offset);
$result=$query-&gt;get()-&gt;result_array();
return $result;
}
function countRows()
{
$query=&quot;select count(*) as count from lfy_users&quot;;
$result=$this-&gt;db-&gt;query($query);
return $result-&gt;result_array();
}
}
?&gt;</pre><p>The first function will fetch and return all data from the <code>lfy_users</code> table to the controller. The second function counts the total number of records. You can also sort columns similarly; good documentation is available on the CodeIgniter Web portal.</p><p>I received many emails in response to the first part of this series, saying that these things can be easily done using simple PHP also. In order that you can understand the logic, I have chosen to use very simple examples. But if you are working on a project of ten thousand lines, and need to change something in your query, I am sure you will waste much time locating the query function, then editing it.</p><p>In the MVC-based framework, you just open the model file and make the change. I have worked on a very large CodeIgniter framework-based project, and believe me, it is totally worth your effort. So Google about this more and more, and keep playing with it. Suggestions and queries are always welcome.<div id="crp_related"><h5>Related Posts:</h5><ul><li><a href="http://www.linuxforu.com/2011/10/lets-play-with-codeigniter/" rel="bookmark" class="crp_title">Let&#8217;s Play with CodeIgniter</a></li><li><a href="http://www.linuxforu.com/2011/08/connecting-to-mysql-with-python-and-php/" rel="bookmark" class="crp_title">Connecting to MySQL With Python and PHP</a></li><li><a href="http://www.linuxforu.com/2009/01/server-side-sessions/" rel="bookmark" class="crp_title">Session Management Using PHP, Part 2: Server-side Sessions</a></li><li><a href="http://www.linuxforu.com/2011/05/drupal-module-development-quick-start-practical-guide/" rel="bookmark" class="crp_title">A Quick-Start Practical Guide to Drupal Module Development</a></li><li><a href="http://www.linuxforu.com/2008/12/session-management-using-php-part-1-cookie-based-sessions/" rel="bookmark" class="crp_title">Session Management Using PHP, Part 1: Cookie-based Sessions</a></li></ul></div>Tags: <a href="http://www.linuxforu.com/tag/application-models/" title="application models" rel="tag">application models</a>, <a href="http://www.linuxforu.com/tag/codeigniter/" title="CodeIgniter" rel="tag">CodeIgniter</a>, <a href="http://www.linuxforu.com/tag/css/" title="CSS" rel="tag">CSS</a>, <a href="http://www.linuxforu.com/tag/database-table/" title="database table" rel="tag">database table</a>, <a href="http://www.linuxforu.com/tag/file-uploads/" title="file uploads" rel="tag">file uploads</a>, <a href="http://www.linuxforu.com/tag/form-validation/" title="form validation" rel="tag">form validation</a>, <a href="http://www.linuxforu.com/tag/forms/" title="forms" rel="tag">forms</a>, <a href="http://www.linuxforu.com/tag/hello-world/" title="hello world" rel="tag">hello world</a>, <a href="http://www.linuxforu.com/tag/html/" title="html" rel="tag">html</a>, <a href="http://www.linuxforu.com/tag/input-type-text/" title="input type text" rel="tag">input type text</a>, <a href="http://www.linuxforu.com/tag/lfy-december-2011/" title="LFY December 2011" rel="tag">LFY December 2011</a>, <a href="http://www.linuxforu.com/tag/login/" title="Login" rel="tag">Login</a>, <a href="http://www.linuxforu.com/tag/pagination/" title="pagination" rel="tag">pagination</a>, <a href="http://www.linuxforu.com/tag/php/" title="PHP" rel="tag">PHP</a>, <a href="http://www.linuxforu.com/tag/table-border/" title="table border" rel="tag">table border</a>, <a href="http://www.linuxforu.com/tag/validation-rules/" title="validation rules" rel="tag">validation rules</a>, <a href="http://www.linuxforu.com/tag/validations/" title="validations" rel="tag">validations</a>, <a href="http://www.linuxforu.com/tag/web-news/" title="Web" rel="tag">Web</a>, <a href="http://www.linuxforu.com/tag/web-programming/" title="web programming" rel="tag">web programming</a><br /> ]]></content:encoded> <wfw:commentRss>http://www.linuxforu.com/2011/12/codeigniter-form-apis-validations-pagination-techniques/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Device Drivers, Part 13: Data Transfer to and from USB Devices</title><link>http://www.linuxforu.com/2011/12/data-transfers-to-from-usb-devices/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=data-transfers-to-from-usb-devices</link> <comments>http://www.linuxforu.com/2011/12/data-transfers-to-from-usb-devices/#comments</comments> <pubDate>Thu, 29 Dec 2011 12:16:25 +0000</pubDate> <dc:creator>Anil Kumar Pugalia</dc:creator> <category><![CDATA[Coding]]></category> <category><![CDATA[Developers]]></category> <category><![CDATA[data transfers]]></category> <category><![CDATA[depmod]]></category> <category><![CDATA[device id]]></category> <category><![CDATA[kernel space]]></category> <category><![CDATA[LFY December 2011]]></category> <category><![CDATA[linux device drivers]]></category> <category><![CDATA[Linux Device Drivers Series]]></category> <category><![CDATA[pci device drivers]]></category> <category><![CDATA[pen drive]]></category> <category><![CDATA[product id]]></category> <category><![CDATA[SCSI]]></category> <category><![CDATA[Universal Serial Bus]]></category> <category><![CDATA[USB]]></category> <category><![CDATA[usb device driver]]></category> <category><![CDATA[usb devices]]></category> <category><![CDATA[usb driver]]></category> <category><![CDATA[usb storage driver]]></category> <category><![CDATA[vendor id]]></category><guid isPermaLink="false">http://www.linuxforu.com/?p=8556</guid> <description><![CDATA[This article, which is part of the series on Linux device drivers, continues from the previous two articles. It details the ultimate step of data transfer to and from a USB device, using...]]></description> <content:encoded><![CDATA[<p><img src="http://cdn.linuxforu.com/wp-content/uploads/2011/12/usb-device-drivers-3-590x341.jpg?d9c344" alt="USB device drivers" title="USB device drivers" width="590" height="341" class="aligncenter size-large wp-image-8558" /><div class="introduction">This article, which is part of the <a href="http://www.linuxforu.com/tag/linux-device-drivers-series/">series on Linux device drivers</a>, continues from the previous <a href="http://www.linuxforu.com/2011/10/usb-drivers-in-linux-1/" title="Device Drivers, Part 11: USB Drivers in Linux">two</a> <a href="http://www.linuxforu.com/2011/11/usb-drivers-in-linux-2/" title="Device Drivers, Part 12: USB Drivers in Linux Continued">articles</a>. It details the ultimate step of data transfer to and from a USB device, using your first USB driver in Linux.</div><p>Pugs continued, &#8220;To answer your question about how a driver selectively registers or skips a particular interface of a USB device, you need to understand the significance of the return value of the <code>probe()</code> callback.&#8221; Note that the USB core would invoke probe for all the interfaces of a detected device, except the ones which are already registered &#8212; thus, while doing it for the first time, it will probe for all interfaces. Now, if the probe returns 0, it means the driver has registered for that interface. Returning an error code indicates not registering for it. That&#8217;s all. &#8220;That was simple,&#8221; commented Shweta.</p><p>&#8220;Now, let&#8217;s talk about the ultimate &#8212; data transfers to and from a USB device,&#8221; continued Pugs.</p><p>&#8220;But before that, tell me, what is this MODULE_DEVICE_TABLE? This has been bothering me since you explained the USB device ID table macros,&#8221; asked Shweta, urging Pugs to slow down.</p><p>&#8220;That&#8217;s trivial stuff. It is mainly for the user-space <code>depmod</code>,&#8221; he said. &#8216;Module&#8217; is another term for a driver, which can be dynamically loaded/unloaded. The macro <code>MODULE_DEVICE_TABLE</code> generates two variables in a module&#8217;s read-only section, which is extracted by <code>depmod</code> and stored in global map files under <code>/lib/modules/&lt;kernel_version&gt;</code>. Two such files are <code>modules.usbmap</code> and <code>modules.pcimap</code>, for USB and PCI device drivers, respectively. This enables auto-loading of these drivers, as we saw the usb-storage driver getting auto-loaded.</p><h2>USB data transfer</h2><p>&#8220;Time for USB data transfers. Let&#8217;s build upon the USB device driver coded in our previous sessions, using the same handy JetFlash pen drive from Transcend, with vendor ID <code>0x058f</code> and product ID <code>0x6387</code>,&#8221; said Pugs, enthusiastically.</p><p>USB, being a hardware protocol, forms the usual horizontal layer in the kernel space. And hence, for it to provide an interface to user-space, it has to connect through one of the vertical layers. As the character (driver) vertical has already been discussed, it is the current preferred choice for the connection with the USB horizontal, in order to understand the complete data transfer flow.</p><p>Also, we do not need to get a free unreserved character major number, but can use the character major number 180, reserved for USB-based character device files. Moreover, to achieve this complete character driver logic with the USB horizontal in one go, the following are the APIs declared in <code>&lt;linux/usb.h&gt;</code>:</p><pre class="brush: c; gutter: false">int usb_register_dev(struct usb_interface *intf, struct usb_class_driver *class_driver);
void usb_deregister_dev(struct usb_interface *intf, struct usb_class_driver *class_driver);</pre><p>Usually, we would expect these functions to be invoked in the constructor and the destructor of a module, respectively. However, to achieve the hot-plug-n-play behaviour for the (character) device files corresponding to USB devices, these are instead invoked in the probe and disconnect callbacks, respectively.</p><p>The first parameter in the above functions is the interface pointer received as the first parameter in both probe and disconnect. The second parameter, <code>struct usb_class_driver</code>, needs to be populated with the suggested device file name and the set of device file operations, before invoking <code>usb_register_dev</code>. For the actual usage, refer to the functions <code>pen_probe</code> and <code>pen_disconnect</code> in the code listing of <code>pen_driver.c</code> below.</p><p>Moreover, as the file operations (write, read, etc.,) are now provided, that is exactly where we need to do the data transfers to and from the USB device. So, <code>pen_write</code> and <code>pen_ read</code> below show the possible calls to <code>usb_bulk_msg()</code> (prototyped in <code>&lt;linux/usb.h&gt;</code>) to do the transfers over the pen drive&#8217;s bulk end-points 0&#215;01 and 0&#215;82, respectively. Refer to the &#8216;E&#8217; lines of the middle section in Figure 1 for the endpoint number listings of our pen drive.</p><div id="attachment_8557" class="wp-caption aligncenter" style="width: 590px"><a href="http://cdn.linuxforu.com/wp-content/uploads/2011/12/figure_19_usb_proc_window_snippet.png?d9c344"><img src="http://cdn.linuxforu.com/wp-content/uploads/2011/12/figure_19_usb_proc_window_snippet-590x448.png?d9c344" alt="USB specifications for the pen drive" title="USB specifications for the pen drive" width="590" height="448" class="size-large wp-image-8557" /></a><p class="wp-caption-text">Figure 1: USB specifications for the pen drive</p></div><p>Refer to the header file <code>&lt;linux/usb.h&gt;</code> under kernel sources, for the complete list of USB core API prototypes for other endpoint-specific data transfer functions like <code>usb_control_msg()</code>, <code>usb_interrupt_msg()</code>, etc. <code>usb_rcvbulkpipe()</code>, <code>usb_sndbulkpipe()</code>, and many such other macros, also defined in <code>&lt;linux/usb.h&gt;</code>, compute the actual endpoint bit-mask to be passed to the various USB core APIs.</p><p>Note that a pen drive belongs to a USB mass storage class, which expects a set of SCSI-like commands to be transacted over the bulk endpoints. So, a raw read/write as shown in the code listing below may not really do a data transfer as expected, unless the data is appropriately formatted. But still, this summarises the overall code flow of a USB driver. To get a feel of a real working USB data transfer in a simple and elegant way, one would need some kind of custom USB device, something like the one available <a href="http://lddk.eSrijan.com/">here</a>.</p><pre class="brush: c; gutter: true; first-line: 1">#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/usb.h&gt;

#define MIN(a,b) (((a) &lt;= (b)) ? (a) : (b))
#define BULK_EP_OUT 0x01
#define BULK_EP_IN 0x82
#define MAX_PKT_SIZE 512

static struct usb_device *device;
static struct usb_class_driver class;
static unsigned char bulk_buf[MAX_PKT_SIZE];

static int pen_open(struct inode *i, struct file *f)
{
    return 0;
}
static int pen_close(struct inode *i, struct file *f)
{
    return 0;
}
static ssize_t pen_read(struct file *f, char __user *buf, size_t cnt, loff_t *off)
{
    int retval;
    int read_cnt;

    /* Read the data from the bulk endpoint */
    retval = usb_bulk_msg(device, usb_rcvbulkpipe(device, BULK_EP_IN),
            bulk_buf, MAX_PKT_SIZE, &amp;read_cnt, 5000);
    if (retval)
    {
        printk(KERN_ERR &quot;Bulk message returned %d\n&quot;, retval);
        return retval;
    }
    if (copy_to_user(buf, bulk_buf, MIN(cnt, read_cnt)))
    {
        return -EFAULT;
    }

    return MIN(cnt, read_cnt);
}
static ssize_t pen_write(struct file *f, const char __user *buf, size_t cnt, loff_t *off)
{
    int retval;
    int wrote_cnt = MIN(cnt, MAX_PKT_SIZE);

    if (copy_from_user(bulk_buf, buf, MIN(cnt, MAX_PKT_SIZE)))
    {
        return -EFAULT;
    }

    /* Write the data into the bulk endpoint */
    retval = usb_bulk_msg(device, usb_sndbulkpipe(device, BULK_EP_OUT),
            bulk_buf, MIN(cnt, MAX_PKT_SIZE), &amp;wrote_cnt, 5000);
    if (retval)
    {
        printk(KERN_ERR &quot;Bulk message returned %d\n&quot;, retval);
        return retval;
    }

    return wrote_cnt;
}

static struct file_operations fops =
{
    .open = pen_open,
    .release = pen_close,
    .read = pen_read,
    .write = pen_write,
};

static int pen_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
    int retval;

    device = interface_to_usbdev(interface);

    class.name = &quot;usb/pen%d&quot;;
    class.fops = &amp;fops;
    if ((retval = usb_register_dev(interface, &amp;class)) &lt; 0)
    {
        /* Something prevented us from registering this driver */
        err(&quot;Not able to get a minor for this device.&quot;);
    }
    else
    {
        printk(KERN_INFO &quot;Minor obtained: %d\n&quot;, interface-&gt;minor);
    }

    return retval;
}

static void pen_disconnect(struct usb_interface *interface)
{
    usb_deregister_dev(interface, &amp;class);
}

/* Table of devices that work with this driver */
static struct usb_device_id pen_table[] =
{
    { USB_DEVICE(0x058F, 0x6387) },
    {} /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, pen_table);

static struct usb_driver pen_driver =
{
    .name = &quot;pen_driver&quot;,
    .probe = pen_probe,
    .disconnect = pen_disconnect,
    .id_table = pen_table,
};

static int __init pen_init(void)
{
    int result;

    /* Register this driver with the USB subsystem */
    if ((result = usb_register(&amp;pen_driver)))
    {
        err(&quot;usb_register failed. Error number %d&quot;, result);
    }
    return result;
}

static void __exit pen_exit(void)
{
    /* Deregister this driver with the USB subsystem */
    usb_deregister(&amp;pen_driver);
}

module_init(pen_init);
module_exit(pen_exit);

MODULE_LICENSE(&quot;GPL&quot;);
MODULE_AUTHOR(&quot;Anil Kumar Pugalia &lt;email_at_sarika-pugs_dot_com&gt;&quot;);
MODULE_DESCRIPTION(&quot;USB Pen Device Driver&quot;);</pre><p>As a reminder, the usual steps for any Linux device driver may be repeated with the above code, along with the following steps for the pen drive:</p><ul><li>Build the driver (<code>pen_driver.ko</code>) by running <code>make</code>.</li><li>Load the driver using <code>insmod pen_driver.ko</code>.</li><li>Plug in the pen drive (after making sure that the <code>usb-storage</code> driver is not already loaded).</li><li>Check for the dynamic creation of <code>/dev/pen0</code> (0 being the minor number obtained &#8212; check <code>dmesg</code> logs for the value on your system).</li><li>Possibly try some write/read on <code>/dev/pen0</code> (you most likely will get a connection timeout and/or broken pipe errors, because of non-conforming SCSI commands).</li><li>Unplug the pen drive and look for <code>/dev/pen0</code> to be gone.</li><li>Unload the driver using <code>rmmod pen_driver</code>.</li></ul><p>Meanwhile, Pugs hooked up his first-of-its-kind creation &#8212; the Linux device driver kit (LDDK) &#8212; into his system for a live demonstration of the USB data transfers.</p><p>&#8220;Aha! Finally a cool complete working USB driver,&#8221; quipped Shweta, excited. &#8220;Want to have more fun? We could do a block driver over it&#8230;,&#8221; added Pugs. &#8220;Oh! Really?&#8221; asked Shweta, with glee. &#8220;Yes. But before that, we need to understand the partitioning mechanisms,&#8221; commented Pugs.<div id="crp_related"><h5>Related Posts:</h5><ul><li><a href="http://www.linuxforu.com/2011/11/usb-drivers-in-linux-2/" rel="bookmark" class="crp_title">Device Drivers, Part 12: USB Drivers in Linux Continued</a></li><li><a href="http://www.linuxforu.com/2011/10/usb-drivers-in-linux-1/" rel="bookmark" class="crp_title">Device Drivers, Part 11: USB Drivers in Linux</a></li><li><a href="http://www.linuxforu.com/2011/05/decoding-character-device-file-operations/" rel="bookmark" class="crp_title">Device Drivers, Part 6: Decoding Character Device File Operations</a></li><li><a href="http://www.linuxforu.com/2011/04/character-device-files-creation-operations/" rel="bookmark" class="crp_title">Device Drivers, Part 5: Character Device Files &#8212; Creation &#038; Operations</a></li><li><a href="http://www.linuxforu.com/2011/02/linux-character-drivers/" rel="bookmark" class="crp_title">Device Drivers, Part 4: Linux Character Drivers</a></li></ul></div>Tags: <a href="http://www.linuxforu.com/tag/data-transfers/" title="data transfers" rel="tag">data transfers</a>, <a href="http://www.linuxforu.com/tag/depmod/" title="depmod" rel="tag">depmod</a>, <a href="http://www.linuxforu.com/tag/device-id/" title="device id" rel="tag">device id</a>, <a href="http://www.linuxforu.com/tag/kernel-space/" title="kernel space" rel="tag">kernel space</a>, <a href="http://www.linuxforu.com/tag/lfy-december-2011/" title="LFY December 2011" rel="tag">LFY December 2011</a>, <a href="http://www.linuxforu.com/tag/linux-device-drivers/" title="linux device drivers" rel="tag">linux device drivers</a>, <a href="http://www.linuxforu.com/tag/linux-device-drivers-series/" title="Linux Device Drivers Series" rel="tag">Linux Device Drivers Series</a>, <a href="http://www.linuxforu.com/tag/pci-device-drivers/" title="pci device drivers" rel="tag">pci device drivers</a>, <a href="http://www.linuxforu.com/tag/pen-drive/" title="pen drive" rel="tag">pen drive</a>, <a href="http://www.linuxforu.com/tag/product-id/" title="product id" rel="tag">product id</a>, <a href="http://www.linuxforu.com/tag/scsi/" title="SCSI" rel="tag">SCSI</a>, <a href="http://www.linuxforu.com/tag/universal-serial-bus/" title="Universal Serial Bus" rel="tag">Universal Serial Bus</a>, <a href="http://www.linuxforu.com/tag/usb/" title="USB" rel="tag">USB</a>, <a href="http://www.linuxforu.com/tag/usb-device-driver/" title="usb device driver" rel="tag">usb device driver</a>, <a href="http://www.linuxforu.com/tag/usb-devices/" title="usb devices" rel="tag">usb devices</a>, <a href="http://www.linuxforu.com/tag/usb-driver/" title="usb driver" rel="tag">usb driver</a>, <a href="http://www.linuxforu.com/tag/usb-storage-driver/" title="usb storage driver" rel="tag">usb storage driver</a>, <a href="http://www.linuxforu.com/tag/vendor-id/" title="vendor id" rel="tag">vendor id</a><br /> ]]></content:encoded> <wfw:commentRss>http://www.linuxforu.com/2011/12/data-transfers-to-from-usb-devices/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Loading Library Files in C++</title><link>http://www.linuxforu.com/2011/12/loading-library-files-in-cpp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=loading-library-files-in-cpp</link> <comments>http://www.linuxforu.com/2011/12/loading-library-files-in-cpp/#comments</comments> <pubDate>Thu, 29 Dec 2011 09:19:10 +0000</pubDate> <dc:creator>Prashant Jadhav</dc:creator> <category><![CDATA[Coding]]></category> <category><![CDATA[Developers]]></category> <category><![CDATA[C]]></category> <category><![CDATA[c compilers]]></category> <category><![CDATA[c programmers]]></category> <category><![CDATA[c programming language]]></category> <category><![CDATA[c style]]></category> <category><![CDATA[C symbols]]></category> <category><![CDATA[C/C++]]></category> <category><![CDATA[dlopen]]></category> <category><![CDATA[dynamic library]]></category> <category><![CDATA[extern c]]></category> <category><![CDATA[init function]]></category> <category><![CDATA[LFY December 2011]]></category> <category><![CDATA[libraries]]></category> <category><![CDATA[library files]]></category> <category><![CDATA[linkage]]></category> <category><![CDATA[main function]]></category> <category><![CDATA[polymorphism]]></category> <category><![CDATA[static functions]]></category> <category><![CDATA[symbol names]]></category> <category><![CDATA[void function]]></category><guid isPermaLink="false">http://www.linuxforu.com/?p=8552</guid> <description><![CDATA[This article demonstrates how to load shared or dynamic library files in programs written in C++, which is not as straightforward as in C. Device drivers and library files have always been associated...]]></description> <content:encoded><![CDATA[<p><img src="http://cdn.linuxforu.com/wp-content/uploads/2011/12/Loading-Library-Files-Opener-Image-590x267.jpg?d9c344" alt="Loading..." title="Loading..." width="590" height="267" class="aligncenter size-large wp-image-8553" /><div class="introduction">This article demonstrates how to load shared or dynamic library files in programs written in C++, which is not as straightforward as in C.</div><p>Device drivers and library files have always been associated with the C programming language, and dominated by C programmers, because of the straightforward symbols of C&#8217;s libraries, which are directly related to the function name. Loading a library in C is simpler than in C++, mainly due to the issue of name mangling, which we will examine later. Another problem of using <code>dlopen</code> in C++ is that the <code>dlopen</code> API supports loading of functions, but in C++, to use the methods of a class, normally, you need to instantiate it.</p><h2>Name mangling</h2><p>In any executable or shared library, all non-static functions are represented by a symbol, which is usually the same as the function name, and represents the start address of the function in memory. In C, the symbol is the same as the function name &#8212; e.g., the symbol for the <code>init</code> function will be <code>init</code>, since no two functions can have the same name.</p><p>However, in C++, because of overloading and polymorphism in classes, it is possible to have the same name for two functions in a program. Hence, it&#8217;s not possible to use the function name as the symbol. To solve this problem of having two functions with the same name, C++ compilers use name-mangling techniques, in which they change the symbol names (you can read more about this on Wikipedia). Name mangling makes it difficult for programmers to access a specific symbol in the compiled shared library file, even if they know the original function name.</p><p>The solution to this issue is to use the special keyword extern &#8220;C&#8221; before the function implementation (i.e., <code>extern "C" void function_name()</code>). This tells the C++ compiler to compile the function in C style &#8212; to keep the symbol name the same as the function name. We can use this keyword to define a function that returns an instance of a class, which also solves the must-instantiate-class problem mentioned earlier.</p><p>Now, let&#8217;s look at an example of building a library, and then loading it. First, let&#8217;s make the interface for the shared library, which we can use to reference the shared library and our main programs:</p><pre class="brush: cpp; gutter: true; first-line: 1">#ifndef TESTVIR H
#define TESTVIR_H

class TestVir
{
public:
  virtual void init()=0;
};

#endif</pre><p>Let&#8217;s start by making a sample shared library, <code>testLib.h</code>:</p><pre class="brush: cpp; gutter: true; first-line: 1">#ifndef TESTLIB_H
#define TESTLIB_H

class TestLib
{
 public:
     void init();
};

#endif</pre><p>In the above header file, we declared a class and the <code>init</code> method as public, as we need to access it later. The next code is <code>testLib.cpp</code>:</p><pre class="brush: cpp; gutter: true; first-line: 1">#include &lt;iostream&gt;
#include &quot;testVir.h&quot;
#include &quot;testLib.h&quot;

using namespace std;
void TestLib::init()
{
   cout&lt;&lt;&quot;TestLib::init: Hello World!! &quot;&lt;&lt;endl ;
}

//Define functions with C symbols (create/destroy TestLib instance).
extern &quot;C&quot; TestLib* create()
{
    return new TestLib;
}
extern &quot;C&quot; void destroy(TestLib* Tl)
{
   delete Tl ;
}</pre><p>Our two-class helper functions with <code>extern "C"</code> and will be used to create and destroy an instance of the shared library class, and serve as access points (entry and exit points) of the library.</p><p>Let us compile and link the above class with the shared and <code>fPIC</code> options to <code>g++</code>:</p><pre class="brush: text; gutter: false; first-line: 1">g++ -shared -fPIC testLib.cpp -o testLib.so</pre><p>Now, let&#8217;s write a program to access this library &#8212; <code>main.cpp</code>:</p><pre class="brush: cpp; gutter: true; first-line: 1">#include&lt;iostream&gt;
#include&lt;dlfcn.h&gt;
#include &quot;testVir.h&quot;

using namespace std;

int main()
{
    void *handle;
    handle = dlopen(&quot;./testLib.so&quot;, RTLD_NOW);
    if (!handle)
    {
           printf(&quot;The error is %s&quot;, dlerror());
    }

    typedef TestVir* create_t();
    typedef void destroy_t(TestVir*);

    create_t* creat=(create_t*)dlsym(handle,&quot;create&quot;);
    destroy_t* destroy=(destroy_t*)dlsym(handle,&quot;destroy&quot;);
    if (!creat)
    {
           cout&lt;&lt;&quot;The error is %s&quot;&lt;&lt;dlerror();
    }
    if (!destroy)
    {
           cout&lt;&lt;&quot;The error is %s&quot;&lt;&lt;dlerror();
    }
    TestVir* tst = creat();
    tst-&gt;init();
    destroy(tst);
    return 0 ;
}</pre><p>In the above program, we used <code>dlopen</code> to load the library, then retrieved references to the symbols for our two access functions with <code>dlsym</code>, and then via these, first invoked the create function to get an instance of the shared object, invoked its <code>init</code> method, and then destroyed the object used to invoke the methods of the C++ class.</p><p>Next, compile and link the program with <code>g++ -ldl main.cpp -o test</code>. The option <code>-ldl</code> is used to link it with <code>libdl.so</code> to use the methods in the <code>dlfcn</code> header file.</p><p>The above scenario is basically used to build a plugin framework, where the plugins are dynamically loaded into the <code>main</code> component.<div id="crp_related"><h5>Related Posts:</h5><ul><li><a href="http://www.linuxforu.com/2011/08/lets-hook-a-library-function/" rel="bookmark" class="crp_title">Let&#8217;s Hook a Library Function</a></li><li><a href="http://www.linuxforu.com/2011/12/gdb-logging-function-parameters-part-2/" rel="bookmark" class="crp_title">GDB Logging Function Parameters, Part 2</a></li><li><a href="http://www.linuxforu.com/2011/04/kernel-debugging-using-kprobe-and-jprobe/" rel="bookmark" class="crp_title">Kernel Debugging Using Kprobe and Jprobe</a></li><li><a href="http://www.linuxforu.com/2011/10/gnu-binutils-collection-of-binary-tools/" rel="bookmark" class="crp_title">GNU Binutils: A Collection of Binary Tools</a></li><li><a href="http://www.linuxforu.com/2011/12/getting-started-with-systemtap/" rel="bookmark" class="crp_title">Getting Started with SystemTap</a></li></ul></div>Tags: <a href="http://www.linuxforu.com/tag/c/" title="C" rel="tag">C</a>, <a href="http://www.linuxforu.com/tag/c-compilers/" title="c compilers" rel="tag">c compilers</a>, <a href="http://www.linuxforu.com/tag/c-programmers/" title="c programmers" rel="tag">c programmers</a>, <a href="http://www.linuxforu.com/tag/c-programming-language/" title="c programming language" rel="tag">c programming language</a>, <a href="http://www.linuxforu.com/tag/c-style/" title="c style" rel="tag">c style</a>, <a href="http://www.linuxforu.com/tag/c-symbols/" title="C symbols" rel="tag">C symbols</a>, <a href="http://www.linuxforu.com/tag/cc/" title="C/C++" rel="tag">C/C++</a>, <a href="http://www.linuxforu.com/tag/dlopen/" title="dlopen" rel="tag">dlopen</a>, <a href="http://www.linuxforu.com/tag/dynamic-library/" title="dynamic library" rel="tag">dynamic library</a>, <a href="http://www.linuxforu.com/tag/extern-c/" title="extern c" rel="tag">extern c</a>, <a href="http://www.linuxforu.com/tag/init-function/" title="init function" rel="tag">init function</a>, <a href="http://www.linuxforu.com/tag/lfy-december-2011/" title="LFY December 2011" rel="tag">LFY December 2011</a>, <a href="http://www.linuxforu.com/tag/libraries/" title="libraries" rel="tag">libraries</a>, <a href="http://www.linuxforu.com/tag/library-files/" title="library files" rel="tag">library files</a>, <a href="http://www.linuxforu.com/tag/linkage/" title="linkage" rel="tag">linkage</a>, <a href="http://www.linuxforu.com/tag/main-function/" title="main function" rel="tag">main function</a>, <a href="http://www.linuxforu.com/tag/polymorphism/" title="polymorphism" rel="tag">polymorphism</a>, <a href="http://www.linuxforu.com/tag/static-functions/" title="static functions" rel="tag">static functions</a>, <a href="http://www.linuxforu.com/tag/symbol-names/" title="symbol names" rel="tag">symbol names</a>, <a href="http://www.linuxforu.com/tag/void-function/" title="void function" rel="tag">void function</a><br /> ]]></content:encoded> <wfw:commentRss>http://www.linuxforu.com/2011/12/loading-library-files-in-cpp/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Content Delivery Network via cdn.linuxforu.com

Served from: www.linuxforu.com @ 2012-02-08 10:44:13 -->
