Wednesday, June 30, 2010

Mixed Mode Windows Programming using C#/C++ -Part 7

This series (of posts) is for the convenience of the attendees of DevCon 2010,Trivandrum India. Here is a Windows dynamic Link Library (Shared Object for Mono on MAC OS X and GNU Linux ) which will be used to demonstrate some features of P/INVOKE mechansim in the .NET Platform

///////////////////////
//
//
// On MS Windows

// -------------

// cl /c /D_WINDOWS DllSave.cpp

// link /out:libMonoWindows.dll /DLL /DEF:libMonoWindows.def DllSave.obj
//

// On GNU/Linux

// ------------

//

// g++ -c fPIC DllSave.cpp

// g++ -shared -o libMonoLinux.so DllSave.o

//

// On MAC OS X

// ------------

// g++ -c -fPIC DllSave.cpp

// g++ -dynamiclib -o libMonoMac.so DllSave.o

//

//

// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//




#include <stdio.h>

#include <math.h>

#include <stdio.h>

#include <string.h>



////////////////////////////////
//
// .NET follows __stdcall calling convention
//
//
//

#ifdef _WINDOWS

#define EXPORT_FUNC __declspec(dllexport)
#define CALL_CONV __stdcall

#else

//---------------------- MAC OS X | LINUX

#define EXPORT_FUNC
#define CALL_CONV


#endif





//////////////////////////////////////////////////////
//
//
// A Simple Function to Add two numbers
//
//
//


extern "C" EXPORT_FUNC int CALL_CONV Add(int a, int b )

{


return a + b;


}





////////
//
//
//
//
//

//
// A Function to demonstrate CallBacks
//
// The function calls a C# method via delegate
//
// (remember cyclic definition of delgate ? )
//
// What is a delegate ?
// Delegates are function Pointers....!
//
// What are function pointers ?
// I told you,it is equivalent to a delegate
//
//
//

extern "C" EXPORT_FUNC void CALL_CONV ListOfSquares(
long (CALL_CONV *square_callback) (int rs)
)

{


for(int i=0; i<10; ++i )
{


double ret = (*square_callback)(i);

printf("Printing from C++ ... %g\n",ret);
}


}




////////////////////
//
//
//
//
//

//
// a clone of lstrcpy WIN API function...
//
//
extern "C" EXPORT_FUNC bool CALL_CONV StringCopy( char *t ,
const char *src )
{


if ( t == 0 || src == 0 )
return false;



if (*src == 0 )

return false;



strcpy(t,src);



return true;


}



///////////////////////////////////

//
// This structure will be passed between
// C# and C++
//
//

struct EventData
{

int I;

char * Message;

};



extern "C" EXPORT_FUNC bool CALL_CONV PutEventData(
EventData *ptr )
{



printf("%s\n",ptr->Message);

printf("%d\n",ptr->I);
return false;




}



On Microsoft Windows , you require a DEF (Module Definition ) file to avoid name mangling by the Visual C++ compiler.

;----------- A module definition file
;------------for Windows DLL
LIBRARY libMonoWindows

EXPORTS
Add
ListOfSquares
StringCopy
PutEventData



Here is a sample C# program which invokes the dll mentioned above... The code works on Windows , Linux and MAC OS X as well.

//////////////////////////////////////////////////////
//
//
// First.cs
//
// On Windows
// -----------
// csc First.cs
//
// on Linux/MAC OS X
// -----------------
// mcs First.cs (in ubuntu, it is gmcs First.cs )
//
//
// When executing , make sure that libMonoWindows.dll
// (under windows ) is in the current directory or
// in the path
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//

#define WINDOWS // MAC_OS_X | GNU_LINUX


using System;

using System.Text;

using System.Runtime.InteropServices;






////////////////////////////////
//
// C# mapping of C/C++ structure...
//
//

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

public struct EventData
{

public int I;

public string Message;

}








public class Test

{


///////////////////////////////////
//
// Declare a delegate which is a mapping
// to function pointer expected by
// ListOfSquares method....
//
//
public delegate long CallBack( int i );




////////////////////////////////////////
//
// This method will be called from C++
//
//
public static long SpitConsole(int i ) {

Console.WriteLine( "Printing from C# {0}",i*i);

return i*i;


}




#if MAC_OS_X

//MONO

[DllImport ("./libMonoMac.so")]

private static extern int Add (int a, int b);


[DllImport ("./libMonoMac.so")]

private static extern long ListOfSquares ( CallBack a );


[DllImport ("./libMonoMac.so")]

private static extern bool StringCopy( StringBuilder dest , String src );
[DllImport ("./libMonoMac.so")]

private static extern bool PutEventData( ref EventData r );



#elif GNU_LINUX // MONO


[DllImport ("./libMonoLinux.so")]

private static extern int Add (int a, int b);


[DllImport ("./libMonoLinux.so")]

private static extern long ListOfSquares ( CallBack a );


[DllImport ("./libMonoLinux.so")]

private static extern bool StringCopy( StringBuilder dest , String src );
[DllImport ("./libMonoLinux.so")]

private static extern bool PutEventData( ref EventData r );




#else
// WINDOWS , MS C#

[DllImport ("libMonoWindows.dll")]

private static extern int Add (int a, int b);



[DllImport ("libMonoWindows.dll")]

private static extern long ListOfSquares ( CallBack a );


[DllImport ("libMonoWindows.dll")]

private static extern bool StringCopy( StringBuilder dest , String src );


[DllImport ("libMonoWindows.dll")]

private static extern bool PutEventData( ref EventData r );



#endif





public static void Main()
{

////////////////////////////////////////////////////
//
// Call the Add method from the DLL
//
Console.WriteLine("Hello DevCon 2010....{0}",Add(2,3));


///////////////////////////////////////////
//
// Call StringCopy

StringBuilder sb = new StringBuilder(256);

StringCopy(sb,"Hello World...");

Console.WriteLine(sb.ToString());



///////////////////////////////////////////////////
//

// This demonstrates how to pass structure to C++
//



EventData rt = new EventData();

rt.I = 13;

rt.Message = "I might be from MONO or Visual C# ........!";

PutEventData(ref rt);



/////////////////////////////
// CallBack Demo
//
ListOfSquares(SpitConsole);
}


}






Happy Coding

Some one Injected a Meme Today !

The term "meme" was coined by Richard Dawkins in his famous title "Selfish Gene" (published in 1976). During conversations we exchange memes without conscious effort. (The science of meme is called Memetics and consult wikipedia page for knowing more )


Some time back , I coined a term "Meme Injection" to describe a phenomena where some one will talk about things which might intrigue us and we will drift away from the current area of interest. What it will bring to us through serendipity is the only matter of solace.

I had posted about a presentation which i was planning to take at an event. The talk is about how we can mix C# , C++ and C++/CLI in a single program.

A guy by the name Anoop Madhusudhanan replied to that by mentioning about Polyglot Programming. For the next half and hour , i enjoyed articles regarding this. ( I am a true Polyglot ! ) He has injected a meme in me.

Tuesday, June 29, 2010

Mixed Mode Windows Programming using C#/C++ -Part 6

I know a developer ( Binny VA ) who has written a series of programs in various programing languages (which he calls "Hello World" method of learning ) to demonstrate it's constructs . His method seems to be a very effective method to learn a new programming language. I will attempt a "Hello World method" program for C++/CLI ( i have not covered classes , interfaces , struct etc )

The program computes the average of series of numbers from the command line.

////////////////////////////////
// average_Cmd.cpp
// A mixed mode C++/CLI Program to demonstrate
// various language features...
//
//
// Written By Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// @ the Visual studio command prompt..
//
// cl /clr average_cmd.cpp
//
//


using namespace System;

///////////////////////////////////
//
// A Function which takes a double array
// as an argument (interior_ptr array)
//
//
double Average( interior_ptr<double> r , int len ) ;

///////////////////////////////////
//
// A Function which takes a ANSI C++ double array
// as an argument (to demonstrate pinning)
//
//

double Ptr_Average(double * r , int len ) ;

//////////////////////////////////////////////////
//
// User Entry Point ( Ask yourself ! - who calls main ?)
//
//
//

int main(array<String^>^ args )
{

if ( args->Length == 0 ) {
Console::WriteLine("No Command line parameters");
return 1;
}

int rs = args->Length;

array<double>^ dbl_array =gcnew array<double>(rs);

/////////////////////////////////////////////
//
// Collect all the command line arguments by converting
// into IEEE 754 floating point...

for(int i=0; i<rs; ++i ) {

try {

dbl_array [i] = Convert::ToDouble(args[i]);
}
catch(Exception^ e ) {

Console::WriteLine("Non numeric character at the cmd line");
return -1;

}
}
//////////////////////////////
// Accumulate
//

double sum = 0.0;
for each(double t in dbl_array ) {
sum +=t;
}

Console::WriteLine("Sum is {0}",sum );

//////////////////////////////////////////////
//
// interior_pointer....
//

interior_ptr<double> s = &dbl_array[0];
double r = Average(s,rs);
Console::WriteLine("Average is {0}",r );

/////////////////////////////////////////////////////
//
//
//
pin_ptr<double>st = &dbl_array[0];
r = Average(st,rs);
Console::WriteLine("Average is {0}",r );


}
/////////////////////////////////
// interior_pointer version of the average...
//
//
//

double Average(interior_ptr<double> r , int len )
{
if (len == 0 )
return 0;
double sum = 0;
int tlen = len;
while (tlen-- )
sum += *r++;

Console::WriteLine("{0}",sum);

return sum/len;

}

/////////////////////////////
//
// Native array version...
//
//
double Ptr_Average(double * r , int len )
{
if (len == 0 )
return 0;
double sum = 0;
int tlen = len;
while (tlen-- )
sum += *r++;

Console::WriteLine("{0}",sum);

return sum/len;

}

Mixed Mode Windows Programming using C#/C++ -Part 5

In this part , we will write a C++/CLI caller for the native DLL we wrote in this series.



///////////////////////////////////////
// CLI_Caller.cpp
//
// a C++/CLI caller for Windows native DLL
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// @ the Visual Studio command prompt...
//
// cl /clr CLI_Caller.cpp
//
using namespace System;
using namespace System::Runtime::InteropServices;

[DllImport("DllSrc.dll")]
int Add(int , int );

int main( array<String^>^ arr )
{
Console::WriteLine("{0}",Add(1,1));

}

Mixed Mode Windows Programming using C#/C++ -Part 4

In this part , we will write a C# program to call DllSrc.Dll created in the previous post.

//////////////////////////////////////////
// CSCaller.cs
//
// A C# program to Call Windows native DLL
// (DllSrc.dll )
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// @ the Visual studio command prompt
//
// csc CSCCaller.cs
//

using System;
using System.Runtime.InteropServices;

public class Test {

[DllImport("DllSrc.dll", EntryPoint="Add")]
static extern int Add(int a , int b );


public static void Main(String [] args ) {

Console.WriteLine("{0}",Add(100,101));

}


}


Consult the P/Invoke documentation and countless articles on the web to learn more about the technique

Mixed Mode Windows Programming using C#/C++ -Part 3

This part will focus on the mechanism for writing Windows Dynamic Link Library. To make matter simple , i am going to write a great sub routine which will add two numbers.


///////////////////////////////////////
//
// A Simple C/C++ source module which will be
// converted to a Win32 Dynamic Link Library
//
//
// cl /c DllSrc.cpp
// link /DLL /DEF:DllSrc.def /out:DllSrc.dll DllSrc.obj
//
//
// using dumpbin utility , we can check whether export is
// properly done
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
//

#include <windows.h>

extern "C" __declspec(dllexport) int __stdcall Add( int a , int b )
{

return a + b;
}





To avoid name mangling by the compiler ( _Functionname@stacksize stuff ...!), we need
to create a module definition file or DEF file.

;DLLSrc.def
;
;--- A DEF file to avoid
;--- Windows name mangling....
;
;Written by Praseed Pai K.T.
; http://praseedp.blogspot.com
;
;

LIBRARY DllSrc
EXPORTS
Add



There are two ways to call a routine from any DLL

a) Static Linking to DLL's Import library
b) Dynamic Loading and linking

Let us look at the option A

////////////////////////////////////
// Caller.cpp
//
// A Program to call Add routine from
// DllSrc.dll
//
// We are going to statically link to the DLL
//
// cl Caller.cpp DllSrc.lib
// Caller.exe
//
//

#include <windows.h>
#include <stdio.h>

extern "C" int __stdcall Add(int , int );


int main( int argc , char **argv )
{

printf("%d\n",Add(2,3));
}




The option B is what P/Invoke do. (It is the way ,
VB used to do and other scripting languages as well )

////////////////////////////////////
// DynCaller.cpp
//
// A Program to call Add routine from
// DllSrc.dll
//
// We are going to dynamically link to the DLL
// (Not an Oxymoron ! ..PINVOKE works like this )
//
// cl DynCaller.cpp
// Caller.exe
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
//
//

#include <windows.h>
#include <stdio.h>




int main( int argc , char **argv )
{
HMODULE handle =(HMODULE)LoadLibrary("DllSrc.dll");

if ( handle == 0 )
{
printf("failed to load the DLL\n");
return -1;
}

int (*AddFunPtr)(int,int) =
( int (*)(int,int))GetProcAddress(handle,"Add");

if ( AddFunPtr == 0 )
{
printf("Could not retrieve the function pointer...\n");
return -2;
}

printf("%d\n",(*AddFunPtr)(2,3));

FreeLibrary(handle);
}






You need to compile the program @ the Visual Studio command prompt.

Mixed Mode Windows Programming using C#/C++ -Part 2

In this part , we will write a program in each of three languages mentioned in the previous post ( C# , C++ , C++/CLI ) to dump command line arguments.

////////////////////////////////
// Dump_Cmd.cpp
// A C++/CLI Hello World...program
// to dump the command line arguments
// to the screen...
//
//
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// @ the visual studio command prompt
//
// cl /clr Dump_cmd.cpp
// Dump_cmd 1 2 3
//
using namespace System;
///////////////////////////////////
//
//
// User entry point....
//
//
//
int main(array<String^>^ args )
{
/////////////////////////////////////////
//
// in a ANSI C/C++ program ,command line parameters
// are of the type char ** (char **argv or char *argv[])
// and by default argv[0] is the executable name..
//
// C++/CLI ( and C# ) won't give the executable name as
// the first parameter
if ( args->Length == 0 ) {
Console::WriteLine("No Command line parameters");
return 0;
}
int rs = args->Length;
for(int i=0; i<rs; ++i ) {
Console::WriteLine("{0} ",args[i]->ToUpper() );
}
}


Let us write the same program using C#

//////////////////////////////////////
// CmdLineDump.cs
//
// A Program to dump the command line
// arguments @ the console
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// csc CmdLineDump.cs
// CmdLineDump.cs
//
//
//
using System;
class DevConDemo {
public static void Main(String [] args ) {
if ( args.Length == 0 )
{
Console.WriteLine("Hello World....");
return;
}
int cmd = args.Length;
for(int i=0;i<cmd;++i )
{
Console.WriteLine("{0}",args[i]);
}
}
}


The C++ version of the same program is given below

/////////////////////////////
//CmdLineDump.cpp
//
//A ANSI C/C++ program to dump the command
//line arguments....
//
//
//Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//cl CmdLineDump.cpp
//CmdLineDump.cpp
//
#include <stdio.h>
int main(int argc , char **argv )
{
if ( argc == 1 ) {
printf("%s\n","No command line arguments");
return 0;
}
int cmd = argc;
for(int i=1; i<cmd; ++i )
{
printf("%s\n",argv[i]);
}
}

Mixed Mode Windows Programming using C#/C++ -Part 1

The Microsoft Visual Studio contains compilers for C# , ANSI C++ and C++/CLI language. C++/CLI language is an extension to ANSI C++ targetted @ the .NET Platform

Let us Write Hello World Programs in each of the dialects

////////////////////////////////
// Pure_CLI.cpp
// A C++/CLI Hello World...program
//
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
// @ the Visual Studio command prompt
//
// cl /clr Pure_CLI.cpp
// Pure_CLI
//
//
using namespace System;
int main(array<String^>^ args )
{
Console::WriteLine("Hello World....");
}


Now we will write the same program using C#

/////////////////////////////////////
// Dump_cmd.cs
//
// A C# program to print "Hello World "
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
// csc Dump_cmd.cs
// Dump_cmd
//
//
using System;
class DevConDemo {
public static void Main(String [] args ) {
Console.WriteLine("Hello World....");
}
}


Let us see How we can write the same program using ANSI C++

/////////////////////////////////
//Ansi_dump_cmd.cpp
//
//A ANSI C/C++ program to print the
//string "Hello world..."
//
//
//Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//cl Ansi_dump_cmd.cpp
//Ansi_dump_cmd
//
//
#include <stdio.h>
int main( int argc , char **argv )
{
printf("%s\n","Hello World...");
}


Comparitive study of programming languages are a good way to master language nuances.

Friday, June 25, 2010

Attributes of a Good programmer

Rather than me elaborating on the issues , let us hear from some one who has given a lot of thought into it @ http://www.acm.org/ubiquity/volume_9/v9i14_kumar.html

Tuesday, June 22, 2010

Windows SDK Programming under Linux !! (Part 2)

This time , let us get serious about writing a Windows Program with message loop. Try to read countless Windows Programming tutorial available elsewhere on the web to understand the programming model of MS Windows ( in a way , it is XLib's cousin ).

Here is how i wrote (stole and adapt rather ) a simple windows program

////////////////////////////////////////////////////////////////
// second.cpp
//
// A Simple Windows SDK Program to test WineLib
// I adapted (stole ) the code from
// http://www.winprog.org/tutorial/simple_window.html
//
// Modified to add Paint Call By Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// Make sure you installed Wine ... and Wine-devel package
//
// copy the file into a directory... in my case second
//
// winemaker --lower-uppercase . [. for the current directory )
// wine second.exe.so
//
//
//


////////////////////////
//
// standard windows header file....!
//

#include <windows.h>

//////////////////////////////////
//
// Every Window has got a WindowClass Name ...
// Button has got classname BUTTON , list box "LISTBOX etc
//
// Class name is they key which Windows uses to retrieve the
// specification to create a window (sounds familiar ..oop guys)
//

const char g_szClassName[] = "myWindowClass";

///////////////////////////////
//
// Customize this program by adding code to the paint routine...
//
//
void CallPaintRoutine( HWND hwnd , HDC paintdc )
{
TextOut(paintdc,10,10,"Hello Windows World...from Linux ",-1);
}

////////////////////////////////////////////////////
//
// The uber message Handler ...every event in the message queue
// is retrieved and dispatched to this place....
//
// A windows program is nothing but ...WinMain followed by
// a big switch statement inside the Window Procedure
//
//
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
//--------------- call the paint routine...
CallPaintRoutine(hwnd,hdc);

EndPaint (hwnd, &ps);
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}

///////////////////////////////////////////
//
// WinMain ...The Entry point.....
//
//
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;

//
// Write the specification of the Window
// and Register it with Window manager (desktop manager)
//
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;

/////////////////////////////////////
//
// lpfnWndProc - LONG POINTER TO FUNCTION WndProc
// give the address of your window procedure here
//
wc.lpfnWndProc = WndProc;

/////////////////////////////////////////////
// When i started windows programming , there was something called
// VBX ( Visual Basic Extensions.. Later superceded by OCX/ActiveX)
// We used to use cbWndExtra a lot ( Window Extra bytes...used to store
// a pointer to a structure )
//
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;

/////////////////////////////////////////
//
// Load standard icons ...if the first parameter is null...
//
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
/////////////////////////////
//
// Set color attributes ...
//
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

////////////////////////////////////////////////////
// Windows looks up in the Wndclass table by using g_szClassName as
// a key ..and retrieves the WNDCLASS and goes to action..
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);

if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

///////////////////////////////////////////
//
// GetMessage stops , when it gets WM_QUIT message
//
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
//////////////////////////////
// We are finished...send ...status to the shell !
//
return Msg.wParam;
}



Here is how i compiled and linked it ...


[sandhya@localhost second]$ gedit second.cpp
[sandhya@localhost second]$ clear
[sandhya@localhost second]$ winemaker --lower-uppercase .
Winemaker 0.7.2
Copyright 2000 Francois Gouget <fgouget@codeweavers.com> for CodeWeavers
Copyright 2004 Dimitrie O. Paun
Copyright 2009 André Hentschel
Scanning the source directories...
Fixing the source files...
second.cpp
Generating project files...
.
[sandhya@localhost second]$ make
wineg++ -c -mno-cygwin -o second.o second.cpp
wineg++ -mwindows -mno-cygwin -m32 -o second.exe.so second.o -lodbc32 -lole32 -loleaut32 -lwinspool -lodbccp32 -luuid
[sandhya@localhost second]$ wine second.exe.so


It was not all gas....!!!!

Monday, June 21, 2010

Objecitve C Programming Tutorial under Linux - Part 22 (using GNUStep)

In this part , we will write a GUI application...

/////////////////////////////
// fourth_gui.m
//
// In Fedora 10
// -------------
// gcc -x objective-c -fconstant-string-class=NSConstantString fourth_gui.m
// -lgnustep-base -lgnustep-gui -o fourth_gui.exe
//
//
// On a Debian Lenny
// -----------------
// gcc -x objective-c -fconstant-string-class=NSConstantString fourth_gui.m
// -I/usr/include/GNUStep -L/usr/lib/GNUStep
// -lgnustep-base -lgnustep-gui -o fourth_gui.exe
//
//
//

#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>

@class NSWindow;
@class NSTextField;
@class NSNotification;

@interface AppController : NSObject
{
NSWindow *window;
NSTextField *label;
}

- (void)applicationWillFinishLaunching:(NSNotification *) not;
- (void)applicationDidFinishLaunching:(NSNotification *) not;

@end

@implementation AppController
- (void) applicationWillFinishLaunching: (NSNotification *) not
{
/* Create Menu */
NSMenu *menu;
NSMenu *info;

menu = [NSMenu new];
[menu addItemWithTitle: @"Info"
action: NULL
keyEquivalent: @""];
[menu addItemWithTitle: @"Hide"
action: @selector(hide:)
keyEquivalent: @"h"];
[menu addItemWithTitle: @"Quit"
action: @selector(terminate:)
keyEquivalent: @"q"];

info = [NSMenu new];
[info addItemWithTitle: @"Info Panel..."
action: @selector(orderFrontStandardInfoPanel:)
keyEquivalent: @""];
[info addItemWithTitle: @"Preferences"
action: NULL
keyEquivalent: @""];
[info addItemWithTitle: @"Help"
action: @selector (orderFrontHelpPanel:)
keyEquivalent: @"?"];

[menu setSubmenu: info
forItem: [menu itemWithTitle:@"Info"]];
RELEASE(info);

[NSApp setMainMenu:menu];
RELEASE(menu);

/* Create Window */
window = [[NSWindow alloc] initWithContentRect: NSMakeRect(300, 300, 200, 100)
styleMask: (NSTitledWindowMask |
NSMiniaturizableWindowMask |
NSResizableWindowMask)
backing: NSBackingStoreBuffered
defer: YES];
[window setTitle: @"Hello World"];

/* Create Label */
label = [[NSTextField alloc] initWithFrame: NSMakeRect(30, 30, 80, 30)];
[label setSelectable: NO];
[label setBezeled: NO];
[label setDrawsBackground: NO];
[label setStringValue: @"Hello World"];

[[window contentView] addSubview: label];
RELEASE(label);
}

- (void) applicationDidFinishLaunching: (NSNotification *) not
{
[window makeKeyAndOrderFront: self];
}

- (void) dealloc
{
RELEASE(window);
[super dealloc];
}

@end


int main(int argc, const char *argv[])
{
NSAutoreleasePool *pool;
AppController *delegate;

pool = [[NSAutoreleasePool alloc] init];
delegate = [[AppController alloc] init];

[NSApplication sharedApplication];
[NSApp setDelegate: delegate];

RELEASE(pool);
return NSApplicationMain (argc, argv);
}



I am pasting the contents of my shell below

[sandhya@localhost cocoa]$ gcc fourth_gui.m -fconstant-string-class=NSConstantString -lgnustep-base -lgnustep-gui -o fourth_gui.exe
[sandhya@localhost cocoa]$ ./fourth_gui.exe

Objecitve C Programming Tutorial under Linux - Part 21 (using GNUStep)

The GNUStep is an attempt to implement the OpenStep specification (which is based on the erstwhile NextStep's Programming Model. ) . Read about GNUStep in the wikipedia as well.

Currently , NextStep's API is called Cocoa ( Apple acquired Next in the year 1996 ) and is the primary API for writing MAC OS X and iPhone/iPad applications

/////////////////////////////
// FString.m
//
// In Fedora 10
// -------------
// gcc -x objective-c -fconstant-string-class=NSConstantString FString.m
// -lgnustep-base -lgnustep-gui -o FString.exe
//
//
// On a Debian Lenny
// -----------------
// gcc -x objective-c -fconstant-string-class=NSConstantString FString.m
// -I/usr/include/GNUStep -L/usr/lib/GNUStep
// -lgnustep-base -lgnustep-gui -o FString.exe
//
//
//

#import <Foundation/Foundation.h>


int main( int argc , char **argv )
{

NSString *r = @"Hello World....";

NSLog(@"Objective C %@ \n ",r);

return 0;
}


I am pasting the console contents over here

[sandhya@localhost cocoa]$ gcc FString.m -fconstant-string-class=NSConstantString -lgnustep-base -lgnustep-gui -o FString.exe
[sandhya@localhost cocoa]$ ./FString.exe
2010-06-22 05:46:46.514 FString.exe[3666] Objective C Hello World....

[sandhya@localhost cocoa]$

Windows SDK Programming under Linux !!

I have heard about Wine Project a lot. In the year 2001 , I had inspected the wine source code tree to write a PE Executable Maker. ( Wine loads MSDOS and Windows Executable using it's own loader )

I installed wine-devel package today. It installed wine-core as well.

mkdir msgbox

gedit test.cpp

Keyed in the following code ....

///////////////////////////////////////////
// test.cpp ( in the directory msgbox )
//
// winemaker --lower-uppercase -iuser32 -igdi32 .
// (. - current directory...)
//
// make
//
// wine dirname.exe.so ( a message box will pop up )
//
//
#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MessageBoxA(GetFocus() , "Hello World....",
"Linux Win32 program - Oxymoron !" ,
MB_OK);

return 0;
}


I am pasting the log of my console for better clarity

[sandhya@localhost msgbox]$ pwd
/home/sandhya/cpp/wine/msgbox
[sandhya@localhost msgbox]$ cat test.cpp
///////////////////////////////////////////
// test.cpp ( in the directory dirname )
//
// winemaker --lower-uppercase -iuser32 -igdi32 .
// (. - current directory...)
//
// make
//
// wine dirname.exe.so ( a message box will pop up )
//
//
#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MessageBoxA(GetFocus() , "Hello World....",
"Linux Win32 program - Oxymoron !" ,
MB_OK);

return 0;
}
[sandhya@localhost msgbox]$ winemaker --lower-uppercase -iuser32 -igdi32 .
Winemaker 0.7.2
Copyright 2000 Francois Gouget <fgouget@codeweavers.com> for CodeWeavers
Copyright 2004 Dimitrie O. Paun
Copyright 2009 André Hentschel
Scanning the source directories...
Fixing the source files...
test.cpp
Generating project files...
.
[sandhya@localhost msgbox]$ ls
Makefile test.cpp
[sandhya@localhost msgbox]$ make
wineg++ -c -mno-cygwin -o test.o test.cpp
wineg++ -mwindows -mno-cygwin -m32 -o msgbox.exe.so test.o -luser32 -lgdi32 -lodbc32 -lole32 -loleaut32 -lwinspool -lodbccp32 -luuid
[sandhya@localhost msgbox]$ wine msgbox.exe.so
[sandhya@localhost msgbox]$


Win32 API is a capable API and it's availability in Linux is a good migration path to linux.


Explore Linux without leaving your comfort zone (of Windows)

Yesterday , from a friend of mine i learned about Wubi (http://wubi-installer.org/) . Enjoy...!

Thursday, June 17, 2010

Compiling and Linking Gtk+ applications

Gtk+ is a very capable C library for GUI Programming. There is a version of WxWidgets Library which piggy backs on it .

On my Fedora 10 , I checked whether development package is installed by issuing

pkg-config --cflags --libs gtk+-2.0


[sandhya@localhost ilug_cross]$ pkg-config --cflags gtk+-2.0
-I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2
[sandhya@localhost ilug_cross]$ pkg-config --libs gtk+-2.0
-lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lgdk_pixbuf-2.0 -lpangocairo-1.0 -lcairo -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lglib-2.0
[sandhya@localhost ilug_cross]$



Went to the GTK+ tutorial @
http://library.gnome.org/devel/gtk-tutorial/stable/c39.html#SEC-HELLOWORLD

////////////////////////////////////////////////////
// hello.cpp
//
// g++ `pkg-config --cflags --libs gtk+-2.0` hello.cpp -o hello.exe
// ./hello.exe
//
// The Code is adapted from GTK+ tutorial
//
//

#include <gtk/gtk.h>

/* This is a callback function. The data arguments are ignored
* in this example. More on callbacks below. */
static void hello( GtkWidget *widget,
gpointer data )
{
g_print ("Hello World\n");
}

static gboolean delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
/* If you return FALSE in the "delete-event" signal handler,
* GTK will emit the "destroy" signal. Returning TRUE means
* you don't want the window to be destroyed.
* This is useful for popping up 'are you sure you want to quit?'
* type dialogs. */

g_print ("delete event occurred\n");

/* Change TRUE to FALSE and the main window will be destroyed with
* a "delete-event". */

return TRUE;
}

/* Another callback */
static void destroy( GtkWidget *widget,
gpointer data )
{
gtk_main_quit ();
}

int main( int argc,
char *argv[] )
{
/* GtkWidget is the storage type for widgets */
GtkWidget *window;
GtkWidget *button;

/* This is called in all GTK applications. Arguments are parsed
* from the command line and are returned to the application. */
gtk_init (&argc, &argv);

/* create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

/* When the window is given the "delete-event" signal (this is given
* by the window manager, usually by the "close" option, or on the
* titlebar), we ask it to call the delete_event () function
* as defined above. The data passed to the callback
* function is NULL and is ignored in the callback function. */
g_signal_connect (window, "delete-event",
G_CALLBACK (delete_event), NULL);

/* Here we connect the "destroy" event to a signal handler.
* This event occurs when we call gtk_widget_destroy() on the window,
* or if we return FALSE in the "delete-event" callback. */
g_signal_connect (window, "destroy",
G_CALLBACK (destroy), NULL);

/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 10);

/* Creates a new button with the label "Hello World". */
button = gtk_button_new_with_label ("Hello World");

/* When the button receives the "clicked" signal, it will call the
* function hello() passing it NULL as its argument. The hello()
* function is defined above. */
g_signal_connect (button, "clicked",
G_CALLBACK (hello), NULL);

/* This will cause the window to be destroyed by calling
* gtk_widget_destroy(window) when "clicked". Again, the destroy
* signal could come from here, or the window manager. */
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_widget_destroy),
window);

/* This packs the button into the window (a gtk container). */
gtk_container_add (GTK_CONTAINER (window), button);

/* The final step is to display this newly created widget. */
gtk_widget_show (button);

/* and the window */
gtk_widget_show (window);

/* All GTK applications must have a gtk_main(). Control ends here
* and waits for an event to occur (like a key press or
* mouse event). */
gtk_main ();

return 0;
}


[sandhya@localhost ilug_cross]$ gedit hello.cpp
[sandhya@localhost ilug_cross]$ g++ `pkg-config --cflags --libs gtk+-2.0` hello.cpp -o hello.exe
[sandhya@localhost ilug_cross]$ ./hello.exe
Hello World
[sandhya@localhost ilug_cross]$

Tuesday, June 15, 2010

Want to write a Spelling corrector ?

Peter norvig is famous among computer science students for his Artificial Intelligence book ( Russel and Norvig ). At present , he is the R&D director of Google inc. He has written an article outlining the central idea of spell checkers and correctors.

You can read the article @ http://norvig.com/spell-correct.html . The site contains implementation of the same code in at least 50 programming languages.

Monday, June 14, 2010

Writing C++ GUI Programs under Linux (Windows/Mac)

Last week, i had taken a session on Compiling and Linking C/C++
programs using the GNU compiler collection @ ILUG,Kochi ( Every
alternate saturday , Developers meet @ JJ's internet cafe,Broadway
Ekm ) . Then , Ashok Shenoy followed it up with a good session on
GDB. He did demonstrate dynamic class loading from shared objects.

This week (Saturday 10 am - 12.30 am,19th ) , i am taking a presentation
on how to compile and run GUI applications.

I will be covering

a) GUI programming with Xlib

b) GUI programming with GTK+/GDK

c) GUI programming with Qt
d) GUI programming with WxWidgets

Due to time limitation , I will be focusing on compilation and the
building ( @ the command line ) of applications.

if there are developers interested in Qt or WxWidgets , i am
interested in talking to them. Pls. try to drop in.

Sinu John was present there and has done a wonderful job by blogging about it @

http://sinujohn.wordpress.com/2010/06/06/a-quick-introduction-to-gcc/



Video advt. board @ the Edapally Jn,Kochi.

I am not sure how many of you have given a thought about ( or seen ) the Video advt. board @ the Edapally jn,Kochi. Yesterday , it was the ad of Alukkas jewellery featuring beautiful Jeniffer Kotwal. Today it was Tamanna Bhatia ( or look alike ) for Chennai Silks. The footages are live with animation ( displacement of the people who are casted in it ) and it is dangerous. Today , a biker got immersed in the ad and it was noise around as he did not move when we got the green signal.

Having Video advt. board in a busy jn. is a sure fire disaster. What are your thoughts about it ?



Thursday, June 10, 2010

Biggest Virus in India

Now a days , when I ask about C/C++ Programming to fresh engineering graduates , they seem to be very confident about their knowledge of the language.

Answer to the next question dissolutions me.

Me:= "Which Compiler you used to Compile your programs ? is it Turbo C++ ?"

Fresher := (most often) "Yes !"

Learning C and C++ using Turbo C++ is equivalent to committing "Harakiri". Turbo C++ was released by the Borland Corporation in the year 1990.

The Compiler has at this point of time , following problems

a) It is a 16 bit Compiler. Most of our machines are 64 bit and our OSes are running in 32 bit mode under 64 bit machines.

b) The compiler can be used to write only real mode programs. Modern day professionals are supposed to write 32 bit or 64 bit protected mode programs

c) it does not support Templates , Exception handling as these things got into the C++ standard in the year 1994/1995.

d) You cannot write today's graphics intensive applications as the single allocation of array cannot be more than 64k in size...

In a way , Pls. enlighten about the problems of learning or teaching Turbo C++ in the college.


IMHO, Turbo C++ compiler and it's IDE is one of the biggest Virus attack in India ( At first , i thought it as a kerala Phenomena).

Solution :- Visual C/C++ express edition is now free for the usage under Windows. For Linux systems , you have got venerable GCC compiler.

P.S :- Electronics For You publishes lot of Turbo C/C++ Programs. That is understandable because to (to learn to ) access CPU registers and Direct Hardware programming Turbo C++ is still a good choice.

Wednesday, June 09, 2010

Books vs WebCasts

Some time back , I had attended an OWASP meeting where in post meeting discussion , i met a guy who has got keen interest in Physics. I boasted about my collection of books (on Physics) , especially three volume Feynman's Lectures on Physics.

Reply from the other guy startled me. He said , "I do not read books any more , it is too slow. Better watch videos ". Despite the fact that i did not like it , i was forced to show a smiling face.


I watched lot of videos today and have started to feel that the guy mentioned above is really wise.

I have got some comfort that Mathematics cannot be learned by watching Videos.

My new maxim is :

if you want to work with a Software Technology or has got amateur interest in some thing , go for WebCasts.

I cannot imagine some one mastering Graduate Level Physics or Math without struggling with thick books.

IMHO , Books are here to stay. Any other thoughts ?

Sunday, June 06, 2010

Welcome to the Independent Programmers group of Kerala (IPGOFKERALA)

Hi all ,
I have been attending Barcamps ,Microsoft User Groups , OWASP
meetups , GTUG , ILUG for the last six years. These Groups are either
Computer Usage centric or Vendor Centric in nature.BarCamps and Owasp
are by far the most nuetral groups i have attended so far. Even
there , the focus is bit narrow.

The IPGOFKERALA plans to exclusively focus on Computer Programming. The
forum is going to be Platform and Technology agnostic. We are not
planning any vendor endorsement.

A Preliminary list of topics which group is interested are

A) Cross Platform C/C++ Programming
B) .NET Programming with Mono and Microsoft tool chain.
C) Java Programming using JDK and GNU tool chain
D) Algorithms
E) Programming Languages
F) History and Folklore (of Programming )

We plan to actively encourage advocacy , bashing (language should not
be foul - it is a request ) of your favourite technology. You can be
religious about technology and is welcome to criticize other
technologies (if you feel so ).

Rest will be decided by you

Happy Programming
Praseed Pai

Friday, June 04, 2010

How GNU Linux can help Developers in their learning ?

For the last three months , i have been using GNU Linux in my laptop as well as Desktop. On my laptop , it is a debian Lenny and on my desktop,it is Fedora 10

Kind of thing which i could do because of this include

a) Experimenting with Cross Platform C++ 
b) Fiddled with Qt and WxWidgets
c) Worked with Mono 
d) Java on Linux (including GCJ )
e) Learned Objective C and GNUStep
d) With the (c) option , i could do a Mac Project
e)  Now, i am working with Mac OS X and iPhone


Other things include

a) Fiddling with UML editors
b) GIMP image editing 
c) Open Office ( i was using this in Windows as well )

I have started using Visual C++ express editions (in Windows ). I do not use pirated software anymore.



Thursday, June 03, 2010

is it Audacity or Stupdity ?

Just now , i happen to see a board advertising the presence of a Clinic. What surprised me was the sentence "Will help in processing Central /State govt. claims!".  is it not against the law ?

P.S:- I am keeping the place confidential with explicit intention.

Wednesday, June 02, 2010

Emacs - I am getting to know why people love it !

I started fiddling with the Emacs editor, yesterday night (It started around evening yesterday when i was waiting for a iPhone SDK download..). The editor seems to be quirky and it takes some time to get used to it. Slowly , i got comfortable with Ctrl (C ) and Alt (M) business.

I estimating that it will take a month or two before i start using the editor the way i use Nano , Gedit or even Vi.

I will also learn Emacs LISP to understand the power of LISP as a Glue language.