Thursday, July 29, 2010

A Nice Article and it's followup discussion

JayaKrishnan K. (alias JK ) has posted an article which he wrote a decade back in the IPGOFKERALA google group.

http://groups.google.com/group/ipgofkerala/browse_thread/thread/2968bb0b0934f46

Discuss this great article (IMHO) and post your comment in the ipgofkerala group.

Friday, July 23, 2010

Participate in the Hacking Competition and Win prize !

Talk is cheap, show me the k0d3 - Hack The k0d3 challenge is available now -http://www.informationsecurityday.com/c0c0n/HackTheCode.pdf

Thursday, July 22, 2010

A Cool article !

A realistic peek into the phenomena of "staying behind" vs "forging ahead" @ http://thedailywtf.com/Articles/Up-or-Out-Solving-the-IT-Turnover-Crisis.aspx

A simple 16 bit assembly language program which can be compiled by TASM under DOSBOX

In the K-mug forum , Praveen Posted an assembly language program from his archive. The program was posted in the context of discussion about C programming internals

 dosseg
.model small
.stack 100h

.data
hello_message db 'Hello, World!',0dh,0ah,'$'

.code
main proc
mov ax,@data
mov ds,ax

mov ah,9
mov dx,offset hello_message
int 21h

mov ax,4C00h
int 21h
main endp
end main





I had just installed the DOSBOX emulator. I tried the program and here is my
screen snapshot



Double click and Zoom in ...the text is clearly visible
I used TASM ( Turbo Assembler ) and Tlink (Turbo Linker ).

Wednesday, July 21, 2010

C/C++ Program without main (or Winmain ) using Visual C++

In the K-mug forum (http://k-mug.org ) , a discussion on main function took place and i recollected a trick which i used to "drag" people into frustration by changing the startup code of the Borland Compilers. I will change the startup code of tiny,small, medium , large and huge model MSDOS applications to invoke a function
called praseed , instead of main. ( This make them wonder why main is not working and some have even thought that their C/C++ skill was not up to the mark )

While answering a post , i remember an article which Matt Pietrek wrote in the MSJ (now MSDN magazine ) about writing "lean" executables. Matt replaced C run time calls with equivalent Win32 calls ( of course , adapting it to confirm to CRT calls )
and showed how one can write lean executables. By "Borrowing" some code from him ,
here is a C/C++ program under Windows which does not use main as entrypoint. It has
some educational value. That is all. ( Consult Matt's original article to learn
about production quality application of this )


//////////////////////////////////////////////////
// test.cpp
//
//
// A Simple Windows C/C++ Program without main.
//
// This was written while trying to answer a post
// in the K-MUG forum (http://k-mug.org )
//
// I have relied on Code written by
// Matt Pietrek for MSDN magazine
// The original source of some of the routines
// used by me can be retrieved from
// http://www.wheaty.net/
//
//
// Since i have purchased his Windows internals and
// Windows 95 system programming secrets , i feel ,
// i have got the liberty to use his code ( !!)
//
// Written By Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// Go To Visual Studio Command prompt
//
// cl /c test.cpp
// link /SUBSYSTEM:CONSOLE test.obj
//
//
//
//

#include <windows.h>

#define _MAX_CMD_LINE_ARGS 128
char * _ppszArgv[_MAX_CMD_LINE_ARGS+1];


//////////////////////////////////////////////////
// Force the linker to include USER32.lib and
// KERNEL32.LIB
//
//
#pragma comment(linker, "/defaultlib:user32.lib")
#pragma comment(linker, "/defaultlib:kernel32.lib")

///////////////////////////////////////
// printf replacement
//
//
//

extern "C" int __cdecl printf(const char * format, ...)
{
char szBuff[1024];
int retValue;
DWORD cbWritten;
va_list argptr;

/////////////////////////////////
//
// use Win API call to format the string
//

va_start( argptr, format );
retValue = wvsprintfA( szBuff, format, argptr );
va_end( argptr );

/////////////////////////
// WriteFile and Console API call to spit
// the output to the console

WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), szBuff, retValue,
&cbWritten, 0 );

return retValue;
}

////////////////////////////
//
// Startup code has to build Argc/Argv array
// before invoking the main.
//
//

int __cdecl _ConvertCommandLineToArgcArgv( void )
{
int cbCmdLine;
int argc;
PSTR pszSysCmdLine, pszCmdLine;

// Set to no argv elements, in case we have to bail out
_ppszArgv[0] = 0;

// First get a pointer to the system's version of the command line, and
// figure out how long it is.
pszSysCmdLine = GetCommandLineA();
cbCmdLine = lstrlenA( pszSysCmdLine );

// Allocate memory to store a copy of the command line. We'll modify
// this copy, rather than the original command line. Yes, this memory
// currently doesn't explicitly get freed, but it goes away when the
// process terminates.
pszCmdLine = (PSTR)HeapAlloc( GetProcessHeap(), 0, cbCmdLine+1 );
if ( !pszCmdLine )
return 0;

// Copy the system version of the command line into our copy
lstrcpyA( pszCmdLine, pszSysCmdLine );

if ( '"' == *pszCmdLine ) // If command line starts with a quote ("),
{ // it's a quoted filename. Skip to next quote.
pszCmdLine++;

_ppszArgv[0] = pszCmdLine; // argv[0] == executable name

while ( *pszCmdLine && (*pszCmdLine != '"') )
pszCmdLine++;

if ( *pszCmdLine ) // Did we see a non-NULL ending?
*pszCmdLine++ = 0; // Null terminate and advance to next char
else
return 0; // Oops! We didn't see the end quote
}
else // A regular (non-quoted) filename
{
_ppszArgv[0] = pszCmdLine; // argv[0] == executable name

while ( *pszCmdLine && (' ' != *pszCmdLine) && ('\t' != *pszCmdLine) )
pszCmdLine++;

if ( *pszCmdLine )
*pszCmdLine++ = 0; // Null terminate and advance to next char
}

// Done processing argv[0] (i.e., the executable name). Now do th
// actual arguments

argc = 1;

while ( 1 )
{
// Skip over any whitespace
while ( *pszCmdLine && (' ' == *pszCmdLine) || ('\t' == *pszCmdLine) )
pszCmdLine++;

if ( 0 == *pszCmdLine ) // End of command line???
return argc;

if ( '"' == *pszCmdLine ) // Argument starting with a quote???
{
pszCmdLine++; // Advance past quote character

_ppszArgv[ argc++ ] = pszCmdLine;
_ppszArgv[ argc ] = 0;

// Scan to end quote, or NULL terminator
while ( *pszCmdLine && (*pszCmdLine != '"') )
pszCmdLine++;

if ( 0 == *pszCmdLine )
return argc;

if ( *pszCmdLine )
*pszCmdLine++ = 0; // Null terminate and advance to next char
}
else // Non-quoted argument
{
_ppszArgv[ argc++ ] = pszCmdLine;
_ppszArgv[ argc ] = 0;

// Skip till whitespace or NULL terminator
while ( *pszCmdLine && (' '!=*pszCmdLine) && ('\t'!=*pszCmdLine) )
pszCmdLine++;

if ( 0 == *pszCmdLine )
return argc;

if ( *pszCmdLine )
*pszCmdLine++ = 0; // Null terminate and advance to next char
}

if ( argc >= (_MAX_CMD_LINE_ARGS) )
return argc;
}
}



///////////////////////////////////////////////
//
// Here is our main !!!!
//
//
//

int fool(int argc , char **argv , char **envp)
{
printf("hello world");
return 0;

}

///////////////////////////////////////////////////////////////////////
// Modified version of the Visual C++ startup code. Simplified to
// make it easier to read. Only supports ANSI programs.
//
// Written by Matt Pietrek , Adapted by Praseed Pai
//
// My Adaptation of Matt's code is buggy , if you have got
// C++ constructor , Global variable initialization
// Do not use this for production application
//
// Download the original code from http://www.wheaty.net/
//
//
extern "C" void __cdecl mainCRTStartup( void )
{
int mainret, argc;
argc = _ConvertCommandLineToArgcArgv( );
mainret = fool( argc, _ppszArgv, 0 );
ExitProcess(mainret);
}




Here is my Command Prompt log



F:\pai\CleanLib>cl /c test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

test.cpp

F:\pai\CleanLib>link /SUBSYSTEM:CONSOLE test.obj
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.


F:\pai\CleanLib>test
hello world
F:\pai\CleanLib>


Enjoy , Happy Coding !

Sunday, July 18, 2010

Compiling 32 bit Applications under 64 bit GNU Linux and MAC OS X

Today , while trying to explore options to port a 32 bit Windows application to
64 bit GNU Linux using Wine , i happen to understand that Wine64 is not as stable
as 32 bit Wine. So , i decided to compile a program to 32 bit binary
sitting under 64 bit Linux and 64 bit MAC OS X.

I wrote a small program which prints the sizeof(long). The sizeof(long)
is 4 in 32 bit mode and 8 in 64 bit mode. Here is a simple program
which tests that.


praseed$ nano test.cpp

#include <stdio.h>

int main( )
{
printf("%d\n",(int)sizeof(long));

}



Compile the program as a 64 bit program under 64 bit Linux and MAC OS X terminal

praseed$ g++ test.cpp
praseed$ ./a.out
8



Now re-compile the program by giving -m32 flag ( -m64 for 64 bit -m32 for 32 bit )


praseed$ g++ -m32 test.cpp
praseed$ ./a.out
4

Saturday, July 17, 2010

C0C0N 2010 - A Two day Security and Hacking Conference

The Information Security Research Association (ISRA) along with Matriux Security Community (http://www.matriux.com/) is organizing a 2 day International Security and Hacking Conference titled c0c0n 2010 in the Port city of Kochi,Kerala,INDIA. The event is also supported by the Kochi City Police. Previously , this event was known as Cyber Safe (you can see the details of the previous events @ http://informationsecurityday.com/cybersafe/index.html )




Dates - 05 - 06 Aug 2010
Location - Hotel Dream,Cochin (Kochi), India

The goal of this event is to promote

Social Awareness
Security Research
A Platform for Security Professionals

As part of the event , there are compettitions like Pre-Con Capture The Flag ( Pre-con CTF ) ,Con CTF and poster compettition. Send in your entry soon.


Twitter Hashtag #c0c0n2010

The Presentations include

Invited talks
Call for Papers ( CFP )
Quick bytes

Earlier, security was the concern of stake holders and network administrators. In the past five years , Secure Programming has become mainstream and every developer worth his salt needs to be aware about his contribution to security ( or lack of it ) in the information delivery stack.

Do not miss this event , if you are in and around Kochi. You can book your tickets
here

Wednesday, July 14, 2010

64 bit Assembly Language using NASM under MAC OS X

Being a person who has worked with 16 bit and 32 bit assembly language , i was eager to transport my skills into the 64 bit world. I did not have a 64 bit OS with me. Now , i am using MAC OS X snow leopard , finally i decided to write a simple Assembler function to be called from 64 bit C/C++ ( GCC ).

For starters , ABI ( Application Binary Interface ) has changed for the 64 bit and there is some difference in parameter passing
mechanism between Linux ABI ( which MAC OS X follows, being a BSD variant ) and Windows 64 bit. ( This means , you cannot have a single code base without conditional compilation ! )

To read about the 64 bit specifics , consult the following page @ http://www.nasm.us/doc/nasmdo11.html

Consult a decent book on 64 bit Assembly language programming ( my favorite is James C Letterman )

Here is my 64 bit assembler code ( in NASM 2.08 )
; rsnasm.s
;
;
; A 64 bit NASM assembly language subroutine
; to add two numbers
;
; Written By Praseed Pai K.T.
; http://praseedp.blogspot.com
;
; NASM which comes with iOS SDK 4 is 32 bit , so
; download from the Nasm site
;
;
; nasm -f macho64 -o rsnasm.o rsnasm.s
;
; long Add( long a , long b )
;
;

section .text
global _Add
_Add:

push rbp
mov rbp,rsp
mov [rbp-8],rdi
mov [rbp-16],rsi
mov rax ,[rbp-16]
add rax ,[rbp-8]
leave
ret



Then , I wrote a 64 bit C/C++ program to test the assembly function.

///////////
// caller.c
//
//
//
// A 64 bit C/C++ program under MAC OS X
//
//
// Written By Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
// gcc caller.c rsnasm.o
//
//

#include <stdio.h>

///////////
//
// Function Proto for the assembly routine
//
//
//
long Add(long , long );

////////////////////
//
// Entry Point
//
//

int main()
{

printf("%ld\n" , Add(2,3));
return 0;
}

The Next World Cup

Prem was sad when his favorite team Argentina lost to the Germany. Tilak recovered from earlier day's shock of Brazil's defeat after that.

Prem =>"These Europeans won the cup for the second time "

Tilak =>" I think , next time it will be Latin America's turn "

Together they went to the Guruji for taking his opinion

Guruji =>" Latin America is like Latrine America now. They are not going to kiss the cup hereafter "!!!!

Tuesday, July 13, 2010

Using 32 bit MASM with Visual C++

In the Visual C++ toolchain , there is a nifty assembler by the name ml.exe ( if you are using 64 bit tools , you will find ml64.exe )

One can write optimized routines in Assembly language and call it from our C programs ( Of course , Algorithmic opimization has to be done before you
venture into these style of micro optimization ). I am going to use my "guinea pig"
function Add (Adding two long numbers ) for this example as well

Here is my assembly language program

; rt.asm
;
;
; A 32 bit MASM Program to be interfaced
; with Visual C++ . The Program assumes
; __cdecl calling convention. The caller
; is supposed to pop the stack.
;
;
; Written by Praseed Pai K.T.
; http://praseedp.blogspot.com
;
;
; @ the Visual studio command prompt (2008 and above )
;
; ml /c rt.asm - This will create rt.obj
;
; Write a calling program in C/C++ and give rt.obj
; at the command line
;
;
.686P
.XMM
.model flat

;// For __cdecl calling convention
;// a under score is prepended before the
;// function....
;//
;// inside the C/C++ routine the prototype
;// should look as
;//
;//
;// extern ""C" long Add( long a , long b );
;//
;// i am assuming that caller is compiled using
;// __cdecl as the default calling convention
;//
;// Caution:-
;//
;// In this program , i am not saving the base pointer
;// to save some space as well as time.
;//
PUBLIC _Add
_TEXT SEGMENT

_Add PROC
mov eax, DWORD PTR [esp+4]
add eax, DWORD PTR [esp+8]
ret 0
_Add ENDP
_TEXT ENDS
END


Compile the code

ml /c rt.asm ( This will generate rt.obj )


The Program can be invoked from a Visual C/C++ Program as follows

////////////////////////////
// caller.cpp
//
// A 32 bit Visual C/C++ Program
// to call a 32 bit Assembler subroutine
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
// cl caller.cpp rt.obj
// rt.obj is a MASM generated object file
//
//

#include <stdio.h>

//////////////////
//
// Function Prototype for Assembler routine
//
extern "C" long Add( long , long );


int main(int argc , char **argv )
{
printf("%d\n",Add(10,1));

}

//Eof caller.cpp


Now compile and link

cl caller.cpp rt.obj

The number 11 should be print at the console

MAC OS X Assembly Language Programming

Back in the year 1996 , one day after reading about POWER PC architecture , i thought x86 is finished and there is no point in learning x86 assembly language programming. Later around 1999 , i got interested in x86 assembler again. This time , the news of Itanium prompted me to stop furthering my foray into that. ( I did some professional assembly language programming for
DOS 16 , DOS 32 (Extended DOS using Phar Lap Dos Extender ) , Win 16 and Win32 Graphics programming )

In the year 2003 , i worked on a Dynamic Compiler Project. The idea was to parse a scripting language and directly execute it using machine language on the fly. We progressed really well , but the client lost interest in the project in between. That time , i decided that there is no point in learning more about x86 instruction set ( I did write a C/C++ library which encodes x86 instruction )

In the year 2010 , i am sitting with a MAC OS X Leoperd with x86 instruction set as a subset. For an intstruction set which was about to die ( if not for AMD's coup against Intel by bringing x86-64 ) a decade ago , it has survived and it is thriving ( x86 processors and it's derivates dominate the entire PC market . MAC OS X now runs only on intel )

As a tribute to this , Let us write a hello world program using NASM ( Net Wide Assembler bundled with Apple developer tools )

; macasm.asm
;
; A Simple MAC OS X Assembly Language Program
;
;
;
; Written by Praseed Pai K.T.
; http://praseedp.blogspot.com
;
;
; At the MAC OS X terminal
;
; nasm -f macho macasm.asm
; ld -o macasm.exe -e entrypoint macasm.o
; ./macasm.exe
;
;
;

section .text ;------- This is the Code Segment

global entrypoint ; global execution start point

entrypoint:
;
; How do i write some thing on to a console
;
; write(1 , "hello world",12);
;

push dword messagelength
push dword message
push dword 1
mov eax , 0x4 ; System call number
sub esp,4 ; decrement stack pointer for MAC OS X system call
int 0x80
add esp,16 ; Clean up the stack after system call

;------- Exit the Program
; exit(0);
;
push dword 0
mov eax , 0x1 ; // System call for exit
int 0x80

section .data

message db "Hello MAC OS X from assembly",13,0xa
messagelength equ $-message ;length



Monday, July 12, 2010

Computing Sine and Cosine at one go

In the mid 90s , people used to use Floating Point instructions to optimize their application code (using inline assembler ). Optimized libraries from Intel and all made this kind of technique an academic curiosity.

Let us visit how ( I ) used to optimize computation of Sine and Cosine using x86's fsincos instruction. You need read about floating point computation specifics of x86 by consulting intel or AMD manuals.

////////////////////////////////////////////
// sincos.cpp
//
// A Simple Visual C++ program which computes
// sine and cosine at one go
//
// This was a optimization feature which i used
// heavily when i used to work with CAD software.
//
// Now, it is not that optimal and there are even
// faster ways to compute it. Use it for the educational
// value.
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// @ the Visual studio command prompt
//
//
// cl sincos.cpp
//
//


#include <stdio.h>

extern "C" void SineCos(double ang, //Angle in radians
double *sin, //retrieve the sine value
double *cos //retrieve the cosine value
)
{

/////////////////////////////////////////
// In olden days , we need to check whether a math co-processer
// is present to issue this instruction. Read about floating point
// processor stack elsewhere to understand what is going on

_asm {

fld QWORD PTR [ang]
fsincos
mov ebx,[cos]
fstp QWORD PTR [ebx]
mov ebx,[sin]
fstp QWORD PTR [ebx]
fwait
}


}

//////////////////////////////////////////
//
// user entry point ...
//
//
int main(int argc , char **argv)
{

///////////////////////
// Convert the angle into radians
// angle*PI/180.0
//
double a = 45*3.14159/180.0;
double sin=0;
double cos=0;
SineCos(a,&sin,&cos);
printf("%g %g \n", sin,cos);

}

//EOF sincos.cpp

A Look at Visual C++ calling conventions

There are umpteen no of ways which we can invoke a function. Every function call is a jmp to a address. How the parameters are passed , how the stack is manipulated to create stack frame etc can be implemented in variety of ways.

Today , we will investigate

a) __cdecl - C/C++ calling convention
Caller cleans up the stack

b) __stdcall - standard calling convention
Callee cleans up the stack

c) __fastcall - uses registers to pass parameters

The following Visual C++ program will demonstrate the usage of tshis

//////////////////////
// rs.cpp
// A Simple Visual C++ Program to demonstrate
// Calling convention , Inline assembler etc
//
//
// Written By Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
// @ the Visual Studio command prompt
//
// cl rs.cpp
//
//
// To really understand the stuff
//
// cl /Fa rs.cpp ( this will generate rs.asm !)
//


#include <stdio.h>

///////////////////////////////////
//
// __cdecl - C/C++ calling convention
//
// Parameters are pushed from right to left and
// caller pops the stack
//

int __cdecl Add(int a , int b )
{
_asm {
MOV EAX , DWORD PTR [ EBP + 8] ;
ADD EAX , DWORD PTR [ EBP + 12] ;
}

}

///////////////////////////////////////////////
//
//
// __stdcall calling convention - Win API calling convention
// Parameters are pushed from right to left , Callee pops the
// stuck
//

int __stdcall Add1(int a , int b )
{
_asm {
MOV EAX , DWORD PTR [ EBP + 8] ;
ADD EAX , DWORD PTR [ EBP + 12] ;
}

}

///////////////////////////////////////////////////
//
// Naked call - We need to set up everything
// The Compiler generates call for __cdecl (default)
//
//
//
int __declspec(naked) Add2( int a , int b )
{

//==================== Prologue
_asm {
push EBP;
MOV EBP,ESP;
SUB ESP , __LOCAL_SIZE;
}

//============================
// Body
//
_asm {
MOV EAX, 20;
}


//===================================================== Epilogue
_asm {
POP EBP;
ret;
}

}

//////////////////////////////////
//
// Entry Point...
//
//
//
//

int main()
{
int a , b;
a=10;
b=20;
int c = Add(a,b);
printf("%d\n",c);

c = Add1(a,b);
printf("%d\n",c);

c = Add2(a,b);
printf("%d\n",c);

}

Friday, July 09, 2010

C++/CLI Tutorial - Part 5

In this part , we will take a look at how we can declare a delgate and instantiate it using C++/CLI.

Basically , delgate is a function prototype and you can assign a function which matches the parameters of the delgates to an instance of delegate. The following C++/CLI program will clarify the stuff for you.

/////////////////////////////
// Delgate.cpp
//
// A Simple C++/CLI program to learn
// about delegate
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// cl /clr Delegate.cpp
//

using namespace System;

/////////////////////////////
// Declare a delgate
//
// delegate <returntype> delegatename ( <paramlist>);
//

delegate int BinaryFunction( int a , int b );

////////////////////////////////////////
//
// Two simple functions
//
//

int Add( int a , int b ) {

return a+b;
}

int Mul( int a , int b ) {

return a*b;
}
//////////////////////////////////////
//
// EntryPoint ....
//
//
//

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

/////////////////////////
// Invoke Mul through a delegate
//
//

BinaryFunction^ binop = gcnew BinaryFunction(Mul);
int s = binop->Invoke(4,2);
Console::WriteLine("{0} ",s);

////////////////////////////////////////
//
// Invoke Add through a delegate
//

binop = gcnew BinaryFunction(Add);
Console::WriteLine("{0}",binop->Invoke(10,2));


//////////////////////////////////
// People say Delgates are like Function Pointers
// When you asked to them about Function Pointers...
// Most people answer that it is a delgate ..!
// Let us put an end to this confusion

int (*BinaryFunction2)(int , int ) =( int (*) (int , int ))Add;
int n = (*BinaryFunction2)(10,2);
Console::WriteLine("{0}" , n);

///////////////////////////////////////////////////
//
// Let us call Mul
//
//

BinaryFunction2 = (int (*)(int,int))Mul;
n = (*BinaryFunction2)(10,2);
Console::WriteLine("{0}" , n);


}

//EOF delgate.cpp

A Simple Analog Clock using MFC

Long time ago , i had written a clock program in MFC. From a old back CD , today i retrieved it.

Here is how we need to build it.

a) Fire Up Visual C++
b) Take the Visual C++ section
c) Select Win32 project , Empty application
d) Add a Cpp file and Paste the code (given below)
e) From the build tab , select link MFC static library
e) Select MBCS character set (default in VS 2008 is unicode )

////////////////////////////////////////////////////
//
// A Simple MFC based Clock Program
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
//
#include <afxwin.h>
#include <afxext.h>
#include <math.h>

//////////////////////////////////
//
// constant to represent PI
//
//
const double PI = 3.14159;

/////////////////////////////
//
// The Main Frame Window
//
//
class CClockFrame :public CFrameWnd
{
private:
RECT _rect;
public:

CClockFrame()
{
HBRUSH brush = (HBRUSH)::CreateSolidBrush(RGB(175,238,238));
CString mywindow = AfxRegisterWndClass(
CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,0,brush,0);

Create(mywindow,"MFC Clock By Praseed Pai");
}

int OnCreate(LPCREATESTRUCT l)
{
CFrameWnd::OnCreate(l);
SetTimer(1,1000,NULL);
return 1;
}

void OnPaint()
{
CPaintDC d(this);
CBrush b(RGB(100,149,237));

int x1 = -200;
int y1 = -220;
int x2 = 210;
int y2 = 200;
Transform(&x1,&y1);
Transform(&x2,&y2);

CRect rect(x1,y1,x2,y2);
d.FillRect(&rect,&b);



CPen p2(PS_SOLID,2,RGB(153,0,0));
d.SelectObject(&p2);

int fhour ;
int fmin ;
int fsec ;

CTime t1;



CTime t = CTime::GetCurrentTime();

fhour = t.GetHour()%12;
fmin = t.GetMinute();
fsec = t.GetSecond();

fhour += fmin/60;
fhour = fhour * 360 / 12;
fmin = fmin * 360 / 60;
fsec = fsec * 360 / 60;

int xs = 120 * cos((-fsec * PI / 180.0)+ PI/2.0);
int ys = 120 * sin((-fsec * PI / 180.0)+ PI/2.0);

int xm = 100 * cos((-fmin * PI / 180.0)+ PI/2.0);
int ym = 100 * sin((-fmin * PI / 180.0)+ PI/2.0);


int xh = 60 * cos((-fhour * PI / 180.0)+ PI/2.0);
int yh = 60 * sin((-fhour * PI / 180.0)+ PI/2.0);

int x = 0;
int y = 0;


Transform(&xh,&yh);
Transform(&x,&y);

d.MoveTo(x,y);
d.LineTo(xh,yh);


Transform(&xm,&ym);


d.MoveTo(x,y);
d.LineTo(xm,ym);


Transform(&xs,&ys);
d.MoveTo(x,y);
d.LineTo(xs,ys);


char *str[] = {"3","2","1","12","11","10","9","8","7","6","5","4"};
CFont f;
f.CreatePointFont(120,"Times New Roman");
d.SelectObject(&f);
d.SetTextColor(RGB(204,0,0));
d.SetBkMode(TRANSPARENT);
for(int i = 0;i < 12;i++)
{
int x = 200 * cos(i * PI / 6);
int y = 200 * sin(i * PI / 6);
Transform(&x,&y);
d.TextOut(x,y,CString(str[i]),strlen(str[i]));

}

}

void Transform(int *px , int *py)
{
::GetClientRect(m_hWnd,&_rect);
int width = (_rect.right-_rect.left)/2;
int height = (_rect.bottom-_rect.top)/2;
*px = *px + width;
*py = height - *py;

}

void OnTimer(UINT n)
{

this->Invalidate(0);

}

DECLARE_MESSAGE_MAP();
};

BEGIN_MESSAGE_MAP(CClockFrame,CFrameWnd)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_TIMER()
END_MESSAGE_MAP()

///////////////////////////////////////
// Our Application Object
//
//
//
//
class CClockApp:public CWinApp
{
public:
int InitInstance()
{
CClockFrame *p ;
p = new CClockFrame();
p->ShowWindow(1);
m_pMainWnd = p;
return 1;
}

};

/////////////////////////
//
// Every Application require a
// Global Application Object instance

CClockApp a;

//Eod main.cpp





Once you build , you will see a clock

var vs dynamic in C# 4.x

C# 4.0 has got support for type inferencing ( using var ) and dynamic typing (using dynamic ). I have seen lot of programmers getting confused about the diferrence between the two. The only similarity between the both is Programmer do not have to worry much about types ( compared to the olden days ). That behavioral equivalence confuses programmers.

Here is my take on it...

Type inferencing => A Compiler feature which detects the type of expressions from constituents of the expression. Done at the compile time. It is static typing with the help of compiler. ( In LINQ , a possible (simple) relational projection with 20 fields has got the potential to create 1048576 types. No human can write that much amount of structs or classes . Only a compiler can do it )

Dynamic Typing => Instead of associating the type with Variable , you associate type
with the Value(it represents). While evaluating the expression , you have got concrete type (as values participate in expressions ) and you need to obey the language semantics (like a string and double cannot be multiplied etc,otherwise run time error will happen). The type of the variable can be mutated by assigning a different value ( of different type - am i going circular here ? ). Behaviorally it
translates into run time type inference.


In short

Type inferencing => Compile Time Type inference
Dynamic Typing => Run time type inference ( behaviorally)

Hope this helps !

Thursday, July 08, 2010

C++/CLI Tutorial - Part 4

The concept of a property was popularized by Borland International's Delphi. In Java , Getter/Setter pattern was used to implement the property. In the .NET world ,
properties are a first class citizen.

Let us write a C# ( no typo here !) class to demonstrate properties and i will write an equivalent C++/CLI class

//////////////////////////////////////////
//
// A Simple C# program for demonstrating
// properties
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// csc prop.cs
// prop.exe
//

using System;

class Person
{
private String _name;
private int _age;

public Person( int age , String name )
{
_name = name;
_age = age;
}

///////////////////////////////////
//
// Let Name be a readonly property
//
public String Name {

get {
return _name;
}

}

//////////////////////////////////
//
//
// A read/Write property
//
public int Age {
get {
return _age;
}

set {
_age = value;
}

}

}

////////////////////////////////////////
//
// EntryPoint class
//

public class Caller
{

public static void Main(String [] args )
{
Person a = new Person(100,"Bjarne");
a.Age = 20;
Console.WriteLine("{0} {1} ",a.Age,a.Name);
}

}


The equivalent C++/CLI program is given below

///////////////////////////////////////
//prop.cpp
//
// A C++/CLI program to demonstrate
// Properties
//
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// cl /clr prop.cpp
//
//
//

using namespace System;

ref class Person
{

private:
String^ _name;
int _age;

public:

Person(int age , String^ name) {
_age=age;
_name=name;
}


property int Age {
int get() {
return _age;
}

void set(int age) {
// you can add some
// validation here
_age = age;
}

}


property String^ Name {

String^ get() {
return _name;
}

}

};

///////////////////////////////////////
// The user entrypoint
//
//
//
//

int main(array<String^>^ args )
{
Person^ a = gcnew Person(55,"Bjarne");
a->Age = 20;
Console::WriteLine("{0} {1}",a->Age , a->Name );
}


C++/CLI Tutorial - Part 3

In this Part , we will learn about the concept of an interface. In ANSI C++ , the interface semantics can be achieved by pure virtual functions.


class Renderable
{

public:
virtual void Draw(HDC& hdc) = 0;
};




if a class has got all it's method as pure virtual it is called an interface. Microsoft has to invent COM/COM+ as a technology to enable interface based programming. The Java Programming Language and C# are the mainstream languages which made interface based programming a mass "movement".

Rather than giving a verbose explanation , the following small program will clarify
the workings of interface...

///////////////////////
// inter.cpp
//
// A C++/CLI Program to demonstrate Interface
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// cl /clr inter.cpp
//

using namespace System;

//////////////////////////
//
// An interface for Rendering object
//
//

interface class Renderable
{
void Translate(int dx,int dy);
void Rotate(double angle);
void Scale(double sx , double sy);
void Render();

};

///////////////////////////////
// Rectanlge
//
//

ref class Rectangle : Renderable
{
public:

virtual void Translate(int dx,int dy) {
Console::WriteLine("Rectangle Translate");
}

virtual void Rotate(double angle){
Console::WriteLine("Rectangle Rotate");
}

virtual void Scale(double sx , double sy){
Console::WriteLine("Rectangle Scale");
}

virtual void Render() {
Console::WriteLine("Render Rectangle");
}


};

///////////////////////////////////////////////
//
//
// Line
//
//
ref class Line : Renderable
{
public:

virtual void Translate(int dx,int dy) {
Console::WriteLine("Line Translate");
}

virtual void Rotate(double angle){
Console::WriteLine("Line Rotate");
}

virtual void Scale(double sx , double sy){
Console::WriteLine("Line Scale");
}

virtual void Render() {
Console::WriteLine("Render Line");
}


};

////////////////////////////////////////////
//
// Ellipse ( When major axis and minor axis becomes
// equal it is a Circle !)
//
//
ref class Ellipse: Renderable
{
public:
virtual void Translate(int dx,int dy) {
Console::WriteLine("Ellipse Translate");
}

virtual void Rotate(double angle){
Console::WriteLine("Ellipse Rotate");
}

virtual void Scale(double sx , double sy){
Console::WriteLine("Ellipse Scale");
}

virtual void Render() {
Console::WriteLine("Render Ellipse");
}


};
///////////////////////////////////////////////
//
// The Entry Point....
//
//
//
int main( array<String^>^ args )
{


/////////////////////////////////////////////
//
// The fundamental truth of OOP is base class reference
// is type compatible with Derived class reference
//
// Renderable^ is type compatible with Line^,Ellipse^
// and Circle^
//
array<Renderable^>^ as = gcnew array<Renderable^>(5);
as[0] = gcnew Rectangle();
as[1] = gcnew Line();
as[2] = gcnew Rectangle();
as[3] = gcnew Line();
as[4] = gcnew Ellipse();

//////////////////////////////////////////
//
// iterate through the Array and render it..!
//

for each (Renderable^ r in as ) {
r->Render();
}


}

C++/CLI Tutorial - Part 2

The .NET platform has value types (can be in stack as well ) and reference types ( always in heap ). In C++/CLI , we need to explicitly qualify a value type with the keyword value.

The following C++/CLI program will demonstrate this

/////////////////////////////
// ValueType.cpp
//
// A Simple C++/CLI Program to demonstrate
// Value Types
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// At the Visual studio command prompt
//
// cl /clr ValueType.cpp
//

using namespace System;

////////////////////////////////////
//
// You need to add a prefix value for Value types
//
//
public value struct ValueHolder
{
int _value;

ValueHolder( int i ) { _value = i ; }

void Set( int a ) { _value = a; }

int Get() { return _value; }

};


//////////////////////////////////////
//
// Calling a Function ... Since ValueHolder
// is a value type , a copy will be passed
// to the function...
//

void ChangeValue( ValueHolder v )
{
v.Set(100);

}

/////////////////////////////////////////
//
// Calling a Function using reference parameter
//

void ChangeValueByRef( ValueHolder& v )
{
v.Set(120);

}

/////////////////////////////////////////
//
// Entry Point ...
//
//

int main( int argc , char **argv )
{
ValueHolder v;
v.Set(1000);
ChangeValue(v);
Console::WriteLine(v.Get());
ChangeValueByRef( v);
Console::WriteLine(v.Get());

}




C++/CLI Tutorial - Part 1

C++/CLI is a Ecma standard language extension to ANSI C++. The only compiler which supports this language at this point of time is Visual C++ compiler.

In the initial posts of this series , i will be writing the same code in C# and C++ at the same time. This will help you to understand the stuff by doing a comparitive analysis.

Let us see a C# program

////////////////////////
// first.cs
// A Simple C# class
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// @ the Visual studio command prompt
//
// cl first.cs
// first.exe
//

using System;

public class Test
{
private String _msg;
public Test( String r ) { _msg = r; }
public void Spit() {
Console.WriteLine(_msg);
}

}
///////////////////////////////////////////
//
// Caller
//
//
public class Caller
{
public static void Main(String [] args ) {
Test r = new Test("Hello C#");
r.Spit();
}

}

// first.cs


The Program is just a typical Hello World style program. I have written a class by the name Test and spits the message saved as an instance variable.

The equivalent C++/CLI Program is given below

///////////////////////
// first.cpp
//
// A simple C++/CLI class
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
// @ the visual studio command prompt
//
// cl /clr first.cpp
// first.exe
//


using namespace System;


public ref class Test
{

private:
System::String^ _msg;

public:
Test(String^ r ) { _msg = r; }
void Spit() {
Console::WriteLine(_msg);
}

};

/////////////////////////////////////
//
// Entry Point ..!
//
//
//
int main( int argc , char **argv )
{

Test^ f = gcnew Test("Ha..Ha...C++/CLI");
f->Spit();
return 0;
}
//first.cpp



The new stuff include

a) ^ - managed pointer ( Pascal syntax like Pointer )
b) gcnew - managed allocator
c) :: instead of .

Wednesday, July 07, 2010

Windows C/C++ API Programming - Part 1

Even though some people might doubt the value of doing Windows Programming at a Low level , the education value ( in understanding Windows ) is very great. This series of articles is meant for College Students who wants to learn about the low level details of their Programming tools.

Let us write a simple hello world program using Windows API

///////////////////////////////////////
// Test.cpp
//
//
// @ the Visual studio command prompt
//
// cl Test.cpp user32.lib
//
// A simple Windows C/C++ API Program
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
//

#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow){

//////////////////////////////////////////
//
// Call the MessageBox function
//
//
MessageBox(GetFocus() , "Hello World....",
"MessageBox - Ver 1.0 !" ,
MB_OK);
return 0;

}




We need to Open the Visual studio command prompt to compile the program.


F:\pai\blog>cl first.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

first.cpp
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.

/out:first.exe
first.obj
first.obj : error LNK2019: unresolved external symbol __imp__MessageBoxA@16 refe
renced in function _WinMain@16
first.obj : error LNK2019: unresolved external symbol __imp__GetFocus@0 referenc
ed in function _WinMain@16
first.exe : fatal error LNK1120: 2 unresolved externals

F:\pai\blog>cl first.cpp user32.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

first.cpp
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.

/out:first.exe
first.obj
user32.lib

F:\pai\blog>

Tuesday, July 06, 2010

The Art of Compiler Construction using C# - a free ebook

Pls. go to the site http://slangfordotnet.codeplex.com/  to download an E-book which outlines the step to build a Compiler ( for a non trivial programming language ) from scratch. The compiler supports Arbitary Expressions , Three data types [ numeric,string , boolean ] , Branching constructs (if ) , Looping ( while ) , Procedure ( Function ) , Recursion to name a few.

The source code contains an interpreter ( Tree Walking interpreter ) and a Compiler (using Reflection.Emit ) . The source can be compiled with Visual C# and the Mono Compiler.

The Direct Download Page is @

http://slangfordotnet.codeplex.com/releases/view/38959

Monday, July 05, 2010

C++ - is it dead on Microsoft Windows ?

"News of my death was an exaggeration" - Mark Twain

Last saturday , i took a session on the creation of Native DLLs (using Visual C++) under Windows. The session started with a simple function
int Add(int a , int b ) [ invoked it from main as well ] and incrementally converted
it into a exportable function. In the process , i explained about extern "C" , Calling conventions ( __stdcall , __thiscall , PASCAL , __cdecl ) , __declspec(dllexport) , Microsoft Name Mangling ( _Fun@paramsize stuff ) , module definition file (.DEF ) , static linking of DLL , Dynamic Loading (LoadLibrary/GetProcAddress) and finally a C# client which uses DllImport ( P/Invoke ) to invoke our DLL.

The session was well recieved by the audience. After the session , couple of guys asked about the relevance of my session to them. They feel Microsoft is moving everything to the managed code and soon there is no need to learn the stuff i discussed. This is a common observation which i have to encounter when i pasted the details of my original presentation ( Mixed Mode Programming in C# and C++ ).

Over a period of time , i have asked this question myself a lot and it required a fair bit of thinking to come up with a rationale to consider C++ as a language for Windows Development.

Back in the 90s , One of the primary use of Visual C++ was for Win32 DLLs (for Visual Basic),COM/DCOM/COM+ components , ATL components for ASP.net , ActiveX controls and ISAPI filters . This positioned C++ ( a language which was designed with a sizeable system programming constructs ) as a Business Application Programming Language.

Move towards Managed memory was a must for the software industry to survive. The java platform and the .net platform is a step in that direction. The reflective capabilities of the modern languages (on the virtual platforms ) made them a force
to reckon int the Business Application development arena. The evolution of open
standards like HTML , CSS and JavaScript (AJAX ) shifted the application arena
to the browser.

Developing Business applications (entirely ) in C++ can become an economic disaster. So , C++ went back to it's original root ( Writing Operating Systems , Compilers , CAD applications , Off line rendering software , Cross Platform Software , Business Components (Engines ) etc ).

Most of the developers in Kerala has seen only LAMP/WAMP , ASP/ASP.net/Winforms,Java/JSP/Swing and Javascript based business application development. Since the momentum in this part of the world tilted towards these stuff, C++ is a language which most developers (here) do not have to give a thought.

C++ is not dead because

a) Microsoft require an Industrial strength C/C++ compilation toolchain to compile their OS and tools ( it contains 40 million lines of C++ code or so )

b) Companies like Adobe , Autodesk , Oracle , CAD software vendors , OS utility writing companies will force Microsoft to continue to develop their compilers to
keep up with the ANSI C++ standard.


c) Millions of Lines of existing C++ code needs to be maintained

d) Cross Platform development ( C++ is the only vendor neutral language in the world)

e) Writing Device Drivers

f) Fine grained Parallel computations ( intel TBB etc )

g) Existence of Thousands of Open Source Cross Platform libraries ( like OpenSSL ) and those needs to be run on Microsoft Windows. OtherWise, Windows will die a natural death

h) C++ developers are a very strong community and if they migrate to other platforms , Microsoft Platform will be the looser

i) The presence of GNU tool chain,Open Watcom , Digital Mars C++ , Lcc-win32 on Windows.

j) C++/CLI - the primary users will be Micrsoft itself. The unmanaged layer can be hidden in the C++/CLI code and managed code can access the managed features.

k) Some systems require deterministic memory management

l) Other languages are weak in their notational terseness for Pointer manipulation.


The Right Question should have been

What is the relevance of Native code programming ? C++ is just a language designed for native code programming . IMHO , it is going to relevant for another fifty years ! ( or as long as platforms exist )

Being a guy who has invested sizeable time of my life with C++ lWindows development , i am going to blog about Visual C++ development ( Cross Platform , Windows Programming , C++/CLI [ managed code] , Mixed mode programming [C#/C++/CLI/ANSI C++],OpenGL/Direct3D programming etc ) also in the future.

The advantage of C++ programming model is the skill you get in Windows can be easily ported to other platforms like Linux and MAC OS X in couple of weeks etc. ( i really mean what i said !. I know one developer who has done it . That is me !!!)

Windows Power Shell - Beware,you will get hooked

My buddy Mr. Shalvin over the phone told me about his exploration of Windows Power Shell. Inspired by him , i tried it. Boy , you have got a Unix like shell under Windows. The Shell commands are called "CmdLets" and we can write it in C#.

How do i start PowerShell ? ( i am using Windows 7 which has got PowerShell)

powershell

What if , if i am using an older version of Windows ?

You can download it from
http://technet.microsoft.com/en-us/scriptcenter/powershell.aspx

Can you tell me some commands ?

ls (dir) - list directory
cp - copy
mv - rename
cls , clear - clear the screen
pwd - present working directory
ps - process status
kill - Kill a process with the id
dir | more - will pause after one page of content



How do i execute a program in the current folder ?

./ExeName | .\ExeName ( ./Caller.exe or .\Caller.exe )


if you are comfortable with bash , korn or any other shell, you will enjoy this a lot.

Today , After invoking the Visual studio 2010 command prompt , i start powershell. Now i am having a Power Shell enabled Visual studio 2010 command prompt. This will
be good for Automated Build systems.

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

In Windows API , there are two variations of function. One for ANSI encoding and the other for Unicode. For example , there is MessageBoxA and MessageBoxW is there in the user32.dll

Let us create a DLL , which has got two useless functions which takes ansi characters and unicode character set.

//////////////////////////
// test.cpp
//
// A Simple DLL to test
// unicode and Ansi character
// set functions
//
//
// @ the Visual studio command prompt
//
// cl /c test.cpp
// link /DLL /out:test.dll test.obj
//
// Written by Praseed Pai
// http://praseedp.blogspot.com
//
//
//

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


////////////////////////////////////////
//
// ANSI version of Length function...
//
//
extern "C" __declspec(dllexport) int __stdcall StrLenA( char *r )
{
return strlen(r);
}

////////////////////////////////
//
// Unicode version of Strlen
//
//
extern "C" __declspec(dllexport) int __stdcall StrLenW( wchar_t *r )
{
return wcslen(r);
}




Since we have not given any DEF file to the linker , The functions will be exported
with MS name mangling as _StrLenW@4 and _StrLenA@4


We will write a C# client program. When we use DllImport Attribute , we need to give CharSet.Ansi for Ansi function and CharSet.Unicode for unicode function..

//////////////////////////////////////////
// Caller.cs
//
// A caller to test Test.dll
//
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
//
//
//


using System;
using System.Runtime.InteropServices;

class Caller
{
[DllImport("test.dll",EntryPoint="_StrLenA@4",
CharSet=CharSet.Ansi)]
static extern int StrLenA( String s );

[DllImport("test.dll",EntryPoint="_StrLenW@4",
CharSet=CharSet.Unicode)]
static extern int StrLenW( String s );

//////////////////////////////////////////////
//
// Entry Point ...
//
public static void Main(String [] args ) {

String s = "Hello World...";
int first = StrLenA(s);
int second = StrLenW( s);
Console.WriteLine("{0} , {1}",first,second);

}

}

Friday, July 02, 2010

Journey to DevCon 2010 venue

I reserved a ticket in the Maveli Express to Tvm and the train is supposed to reach 1.50 am @ the aluva railway station. I packed everything by 11 pm (friday ) and had a chat with Sreejumon regarding the arrangements.

Around 1.15 am , i asked my brother to drop me at the Rly station. The train arrived on time and i slept immediately. Around 5.30 am , i decided to get down @ the Kollam rly. station (instead of Trivandrum Central ) around 5.45 am. From the Kollam rly. station , i got a vehichle uptil Attingal ( an Omni returning back to Attingal droping some cargo ). From Attingal , i got a KSRTC vehichle to Kariyavattom jn. My friend (Sanjay George) picked me up and i could take a quick shower (at his newly purchased Villa ) to reach the venue.

A Cool book

For the last fifteen years , i have seen a particular book being mentioned wherever Object Oriented Programming is mentioned.
The Title of the book is "SmallTalk 80: it's design and implementation"

Since i work with Objective C Programming Language , i was curious to know the intellectual lineage of the Language. The pundits say the following

a ) C++ , Java and C# follow the Simula model of OOP
b) Objective C follow SmallTalk model of OOP

I visited Wiki page of the SmallTalk language and happen to click on a link. From there , i happen to see an electronic copy of the
SmallTalk book which i mentioned above

Download the PDF version of the book from http://stephane.ducasse.free.fr/FreeBooks/BlueBook/

The expectation about the reader

The Task of Book-Reading
----------------------
This book takes for granted a certain amount of computer literacy on
the part of its reader. We assume that the reader
• knows why software systems are a good idea;
• is a programmer or programming-language designer who knows at
least one language well;
• is familiar with the idea of expression syntax and of evaluation of
expressions by an interpreter;
• is familiar with sequencing of instructions in a computer, control
structures such as iteration and recursion, and the role of data
structures;
• is concerned with the need to have better control of the represen-
tation and manipulation of information in a computing system;
and
• is seeking new ideas for how to create a software (application) sys-
tem that supports the ability to express a software solution in a
way that is closely associated with the natural expression of the so-
lution.


Other free titles can be acessed from

http://stephane.ducasse.free.fr/FreeBooks.html

A "mouth watering" Training Program

I came across Walter Bright (http://en.wikipedia.org/wiki/Walter_Bright ) in the mid 90s while reading "Design and the Evolution of C++" by Bjarne Stroustrup. In his book, Stroustrup mentions about Walter Birght as a solo compiler writer who will put Compiler Writers out of their business. He was the lone implementor of Zortech C++ ( the first C++ compiler released for DOS platform. Borland released their C++ compiler in the year 1990 and Microsoft in May 1992 )

He is also the creator of D Programming Language.

I was searching for Herb Sutter to read about C++/CLI and stumbled upon the following page

@ http://www.astoriaseminar.com/compiler-construction.html

Thursday, July 01, 2010

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

In this part , we will see how one can call a C++ class from C# without the support of COM or wrapping the objects in a extern "C" method.

Here is my ANSI C++ class (CPP_UNMANAGED.cpp)

///////////////////////////////////////////////
//
// CPP_UNMANAGED.cpp
//
// A Simple C++ which will be exported from a
// DLL. The class will be instantiated from
// a C# module
//
// @ the Visual C++ command prompt:-
//
// cl /LD CPP_UNMANAGED.cpp
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//
//
//

#include <stdio.h>

class __declspec(dllexport) RawClass
{

private:
double _val;
public:
RawClass( double p=0 ) {
_val = p;
}

void AddAndEmit(double slack ) {
printf("%d\n",(int)(_val+slack) );

}

static RawClass *RawClassFactory(double t) {
return new RawClass(t);
}

static void DeleteObject(RawClass *r ) {
delete r;
}

};




At this Visual studio command line compile this using

cl /LD CPP_UNMANAGED.cpp

This will created CPP_UNMANAGED.dll

Invoke the Dumpbin utility to see the Managled name

dumpbin /EXPORTS CPP_UNMANAGED.dll

Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.


Dump of file CPP_UNMANAGED.dll

File Type: DLL

Section contains the following exports for CPP_UNMANAGED.dll

00000000 characteristics
4C2D2AC6 time date stamp Fri Jul 02 05:24:46 2010
0.00 version
1 ordinal base
6 number of functions
6 number of names

ordinal hint RVA name

1 0 00001000 ??0RawClass@@QAE@N@Z
2 1 000010B0 ??4RawClass@@QAEAAV0@ABV0@@Z
3 2 000010D0 ??_FRawClass@@QAEXXZ
4 3 00001020 ?AddAndEmit@RawClass@@QAEXN@Z
5 4 00001090 ?DeleteObject@RawClass@@SAXPAV1@@Z
6 5 00001050 ?RawClassFactory@RawClass@@SAPAV1@N@Z

Summary

3000 .data
3000 .rdata
2000 .reloc
B000 .text



Write the DLL import statement consulting the mangled name...

//////////////////////////////////////////////////////
//caller.cs
//
//
//This C# program will call a ANSI C++ class
//(without using Com interop )...bit ugly !
//
//
//Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
// @ the Visual studio command prompt
// csc caller.cs
//

using System;
using System.Runtime.InteropServices;

class Test
{
/////////////////////////////////////////
//
// call the Factory method to instantiate the
// ANSI C++ Object
//
[DllImport("CPP_UNMANAGED.dll",
EntryPoint="?RawClassFactory@RawClass@@SAPAV1@N@Z")]
extern static IntPtr RawClassFactory(double t );

/////////////////////////////////////////////
//
// Delete the Object
//
[DllImport("CPP_UNMANAGED.dll",
EntryPoint="?DeleteObject@RawClass@@SAXPAV1@@Z")]
extern static void DeleteObject(IntPtr obj);

////////////////////////////////////
//
// Call the AddAndEmit method.... not the
// ThisCall directive. When you call a C++
// method , there is a implicit this pointer
// we are passing that !.....
//
// Now you know the mechanism of this pointer....
// it is just a function call...
//
[DllImport("CPP_UNMANAGED.dll",
EntryPoint="?AddAndEmit@RawClass@@QAEXN@Z",
CallingConvention=CallingConvention.ThisCall)]
extern static void AddAndEmit(IntPtr obj,double i);


/////////////////////////////////////////////
//
// Entry Point....
//
public static void Main(String [] args )
{
IntPtr p = RawClassFactory(10.0);
AddAndEmit(p,2);
DeleteObject(p);
}


}


compile the C# module ( caller.cs )

csc caller.cs

execute it !... This code will print 12

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

In this part, i will demonstrate how we can pass array of ints and doubles
to a C++ function. For the purpose , i have build a DLL. The source code
is as given below

/////////////////////////////////
//
// minarray.cpp
//
// The following code is compiled into
// a DLL under windows.
//
// cl /c minarray.cpp
// link /DLL /out:libWindows.dll minarray.obj
//
//
// Since we are not using DEF file ,
// Visual C++ compiler will do some name
// mangling..._FnName@paramsize
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//

#include <stdio.h>

//////////////////////////////
//
// Computes the minimum value in an int array
//
//

extern "C" _declspec(dllexport) int __stdcall
MinArray(int* pData, int length)
{

int minData = pData[0];
for(int pos = 1; pos < length; pos++)
{

if(pData[pos] < minData)
minData = pData[pos];
}

return minData;
}
///////////////////////////////////////////
//
//
// Computes the minimum for a double array
//
//

extern "C" _declspec(dllexport) double __stdcall
MinArrayD(double* pData, int length)
{

double minData = pData[0];
for(int pos = 1; pos < length; pos++)
{

if(pData[pos] < minData)
minData = pData[pos];
}

return minData;
}
//////////////////////////////////////////
//
// Computes the arithematic mean of an array
//
//
//

extern "C" _declspec(dllexport) double __stdcall
Average(double* pData, int length)
{

double minData = pData[0];
for(int pos = 1; pos < length; pos++)
{

minData += pData[pos];
}
return minData/length;
}



Given below is the caller...

//////////////////////////////
//
// a C# program to demonstrate
// passing of arrays to C/C++
// sub routines..
//
//
// Written by Praseed Pai K.T.
// http://praseedp.blogspot.com
//
//

using System;
using System.Runtime.InteropServices;

public class test
{

[DllImport("libWindows.dll",EntryPoint="_MinArray@8")]
extern static int MinArray(int[] pData, int length);
[DllImport("libWindows.dll",EntryPoint="_MinArrayD@8")]
extern static double MinArrayD(double[] pData, int length);
[DllImport("libWindows.dll",EntryPoint="_Average@8")]
extern static double Average(double[] pData, int length);


//////////////////////////////////////
//
//
// User entry point..
//
//
public static void Main() {

int [] rs = new int [] { 10,-11,20};

int rt = MinArray(rs,rs.Length);
Console.WriteLine(rt);

double [] rr = new double [] { 10.0,-11.0,20.0};

double drt = MinArrayD(rr,rr.Length);
Console.WriteLine(drt);


drt = Average(rr,rr.Length);
Console.WriteLine(drt);

double [] srr = new double [10];
srr[0]= 10.0;
srr[1]=100;
drt = Average(srr,2);
Console.WriteLine(drt);
}
}