Wednesday, March 21, 2012

C Call C++

[1] ParaShift.com
     isocpp.org/wiki/faq/mixing-c-and-cpp
[2] Bytes.com
[3] research.att.com


From [3]
------------------------
 // C++ code:
 extern "C" void f(int);
 void f(int i){
  // ...
 }
 /* C code: */
 void f(int);
 void cc(int i){
  f(i);
  /* ... */
 }

// C++ code:
 class C {
  // ...
  virtual double f(int);
 };

 extern "C" double call_C_f(C* p, int i) // wrapper function
 {
  return p->f(i);
 }

 /* C code: */
 double call_C_f(struct C* p, int i);
 void ccc(struct C* p, int i){
  double d = call_C_f(p,i);
  /* ... */
 }


 // C++ code:
 void f(int);
 void f(double);

 extern "C" void f_i(int i) { f(i); }
 extern "C" void f_d(double d) { f(d); }

 /* C code: */
 void f_i(int);
 void f_d(double);

 void cccc(int i,double d){
  f_i(i);
  f_d(d);
  /* ... */
 }




From [1]
-----------------------------
main.cpp

// This is C++ code
#include "Fred.h"
int main()
{
  Fred fred;
  c_function(&fred);
} 



c-function.c

/* This is C code */
#include "Fred.h"

void c_function(Fred* fred){
   unsigned char lc;

   cplusplus_callback_function(fred);
   lc=Cplusplus_CallbackFunction_Wilma(456,fred);
   printf("return of C++ Wilma: %d\n",lc);
} 


Fred.cpp

// This is C++ code
#include "Fred.h"
#include  /*std::cout<<*/

//Fred::Fred() : a_(0) { }
Fred::Fred() { }

void Fred::wilma(int a) { std::cout<<"wilma(arg) print arg "<        

Fred* cplusplus_callback_function(Fred* fred){
  fred->wilma(123);
  return fred;
} 

//Provide access of C++ methods from C code.
unsigned char Cplusplus_CallbackFunction_Wilma(int a, Fred* fred){
  fred->wilma(a);
  return(0);
} 


Fred.h

 
/* This header can be read by both C and C++ compilers */
 #ifndef FRED_H
 #define FRED_H

 #ifdef __cplusplus
   class Fred {
   public:
     Fred();
     void wilma(int);
   private:
     int a_;
   };
 #else
   typedef struct Fred  Fred;

 #endif


 #ifdef __cplusplus
 extern "C" {
 #endif


 #if defined(__STDC__) || defined(__cplusplus)
   extern void c_function(Fred*);   /* ANSI C prototypes */
   extern Fred* cplusplus_callback_function(Fred*);
   extern unsigned char Cplusplus_CallbackFunction_Wilma(int a, Fred* fred);
 #else
   extern void c_function();        /* K&R style */
   extern Fred* cplusplus_callback_function();
 #endif

 #ifdef __cplusplus
 }

 #endif
 #endif /*FRED_H*/





Makefile
DESTDIR  = ./
PROGRAM = $(DESTDIR)/CCallCplusplus
SRCDIR = ./
INCL = -I ./
CP = g++
C = gcc
#C = arm-none-linux-gnueabi-g++

OBJS := $(addprefix $(DESTDIR)/,main.o Fred.o c-function.o)
DEBUG = -g
CFLAGS = -Wall $(DEBUG)

all:$(PROGRAM)

$(PROGRAM): $(OBJS)
 $(CP) -o $(PROGRAM) $(OBJS) -lpthread

$(DESTDIR)/%.o:$(SRCDIR)/%.cpp
 $(CP) -c $(CFLAGS) $< -o $@ $(INCL)

$(DESTDIR)/%.o:$(SRCDIR)/%.c
 $(C) -c $(CFLAGS) $< -o $@ $(INCL)

clean :
 rm -f $(OBJS)
 rm -f $(PROGRAM)



Result:

wilma(arg) print arg 123
wilma(arg) print arg 456
return of C++ Wilma: 0

Tuesday, March 6, 2012

Shell exit on Error

[1] A little madness
[2] Fvue.nl WiKi

Bash Tip: Exit on Error

Back in my post Your Next Programming Language I mentioned I would post occassional tips about bash scripting. As soon as I started writing my next script, it occured to me: the first thing I always do when writing a new bash script is set the errexit option:

set -e

This option makes your script bail out when it detects an error (a command exiting with a non-zero exit code). Without this option the script will plough on, and mayhem often ensues. In all the noise generated it can be a pain to found the root cause of the problem. So I make it a rule to set this option and fail as early as possible.


[2]
----------------------
Exit on error

Bash can be told to exit immediately if a command fails. From the bash manual ("set -e"):

"Exit immediately if a simple command (see SHELL GRAMMAR above) exits with a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of a && or || list, or if the command's return value is being inverted via !. A trap on ERR, if set, is executed before the shell exits."

To let bash exit on error, different notations can be used:

Specify `bash -e' as shebang interpreter
Start shell script with `bash -e'
Use `set -e' in shell script
Use `set -o errexit' in shell script
Use `trap exit ERR' in shell script

Specify `bash -e' as the shebang interpreter

Sunday, February 26, 2012

How to generate patch under Linux

[1] Linux byexamples


First, how to create patch file?
------------------------------------
Patch file is a readable file that created by diff with -c (context output format). It doesn’t matter and if you wanna know more, man diff. To patch the entire folder of source codes(as usually people do)I do as bellow:

Assume Original source code at folder Tb01, and latest source code at folder Tb02. And there have multiple sub directories at Tb01 and Tb02 too.

diff -crB Tb01 Tb02 > Tb02.patch


-c context, -r recursive (multiple levels dir), -B is to ignore Blank Lines.
I put -B because blank lines is really useless for patching, sometimes I need to manually read the patch file to track the changes, without -B is really headache.

How to patch?
-------------------------
First of all, please do a dry-run before really patch it. Bare in mind, patch will be working very specifically. Let say the version 3 Tb03.patch is use to patch from Tb02, if you apply patch on Tb01, sometimes it will corrupt your source code. So, to make sure it works, do a dry run. Dry-run means a fake-test, do it at the directory of the source code targeted to patch.

Doing dry-run like this:

patch --dry-run -p1 -i Tb02.patch

The success output looks like this:

patching file TbApi.cpp
patching file TbApi.h
patching file TbCard.cpp
...

The failure ouptut looks like this:

patching file TbCard.cpp
Hunk #2 FAILED at 585.
1 out of 2 hunks FAILED -- saving rejects to file TbCard.cpp.rej
patching file TbCard.h
Hunk #1 FAILED at 57.
Hunk #2 FAILED at 77.
Hunk #3 succeeded at 83 with fuzz 1 (offset -21 lines).
....

At last, if the dry-run is giving good result, do this and enjoy the compilation.

patch -p1 -i Tb02.patch

References:
1. Network Theory Ltd Patch Intro
2. How to create and use a patch in Linux

Sunday, January 8, 2012

Changing MAC address under Linux Command Line

[1] Ref


$ ifconfig -a | grep HWaddr
eth0  Link encap:Ethernet HWaddr 00:80:48:BA:d1:20
 

# ifconfig eth0 down
# ifconfig eth0 hw ether 00:80:48:BA:d1:30
# ifconfig eth0 up
# ifconfig eth0 |grep HWaddr
 
 
In Linux, Windows, Mac OS X, or a different operating system, 
changing MAC address is only temporary. 
 
Once you reboot your machine, the operating system reflects the 
physical MAC address burnt in your network card and not the MAC address you set.
 

Thursday, January 5, 2012

Set Time and Date under Linux

[1] Linuxsa.org

Setting the system clock

To set the system clock under Linux, use the date command. As an example, to set the current time and date to July 31, 11:16pm, type ``date 07312316'' (note that the time is given in 24 hour notation). If you wanted to change the year as well, you could type ``date 073123161998''. To set the seconds as well, type ``date 07312316.30'' or ``date 073123161998.30''. To see what Linux thinks the current local time is, run date with no arguments.

Setting the hardware clock

To set the hardware clock, my favourite way is to set the system clock first, and then set the hardware clock to the current system clock by typing ``/sbin/hwclock --systohc'' (or ``/sbin/hwclock --systohc --utc'' if you are keeping the hardware clock in UTC). To see what the hardware clock is currently set to, run hwclock with no arguments. If the hardware clock is in UTC and you want to see the local equivalent, type ``/sbin/hwclock --utc''

Wednesday, December 28, 2011

FW: File size limit exceeded error under Linux and solution

[1] From Cyberciti.biz

File size limit exceeded error under Linux and solution

$ulimit -a

core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 227
virtual memory (kbytes, -v) unlimited

Monday, September 26, 2011

String processing in C++ using string library

[1] String library in C++ library.
[2] Get decimalhttp://www.blogger.com/img/blank.gif value from string.
[3] iStringStream Class in C++ library.
[4] iStringStream operator.
[5] Print hex value in C++
[6] IP address validation using GNU C++ library.
[7]String to number and vice versa in C++/C Lib.



IP ADDRESS VALIDATION [6]
-------------------------
inet_ntop(), inet_pton().



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

// IPv4 demo of inet_ntop() and inet_pton()

struct sockaddr_in sa;
char str[INET_ADDRSTRLEN];

// store this IP address in sa:
inet_pton(AF_INET, "192.0.2.33", &(sa.sin_addr));

// now get it back and print it
inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN);

printf("%s\n", str); // prints "192.0.2.33"


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

// IPv6 demo of inet_ntop() and inet_pton()
// (basically the same except with a bunch of 6s thrown around)

struct sockaddr_in6 sa;
char str[INET6_ADDRSTRLEN];

// store this IP address in sa:
inet_pton(AF_INET6, "2001:db8:8714:3a90::12", &(sa.sin6_addr));

// now get it back and print it
inet_ntop(AF_INET6, &(sa.sin6_addr), str, INET6_ADDRSTRLEN);

printf("%s\n", str); // prints "2001:db8:8714:3a90::12"


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

// Helper function you can use:

//Convert a struct sockaddr address to a string, IPv4 and IPv6:

char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen)
{
switch(sa->sa_family) {
case AF_INET:
inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr),
s, maxlen);
break;

case AF_INET6:
inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),
s, maxlen);
break;

default:
strncpy(s, "Unknown AF", maxlen);
return NULL;
}

return s;
}




STRING PROCESSING IN C 'atoi','atof','sscanf' [2]
--------------------------
The old C way (deprecated):



const char* str_int = "777";
const char* str_float = "333.3";
int i = atoi(str_int);
float f = atof(str_float);


A better way:

const char* str_int = "777";
const char* str_float = "333.3";
int i;
float f;

if(EOF == sscanf(str_int, "%d", &i))
{
//error
}

if(EOF == sscanf(str_float, "%f", &f))
{
//error
}





STRING PROCESSING IN C++ USING 'istringstream' CLASS[2][3]
--------------------------


#include
#include
#include

template
bool from_string(T& t,
const std::string& s,
std::ios_base& (*f)(std::ios_base&))
{
std::istringstream iss(s);
return !(iss >> f >> t).fail();
}

int main()
{
int i;
float f;

// the third parameter of from_string() should be
// one of std::hex, std::dec or std::oct
if(from_string(i, std::string("ff"), std::hex))
{
std::cout << i << std::endl;
}
else
{
std::cout << "from_string failed" << std::endl;
}

if(from_string(f, std::string("123.456"), std::dec))
{
std::cout << f << std::endl;
}
else
{
std::cout << "from_string failed" << std::endl;
}
return 0;
}

/* output:
255
123.456
*/




STRING PROCESSING IN C++ BUILDER
-----------------------------------


//Text.SubString(1,2).c_str()
sprintf(lcTemp, "%s", Pan1Edit2PacMac->Text.SubString(1,2).c_str());

//Text.ToInt()
lsPacHwRev.HwRevChkSum=Pan1Edit4NewHwRev->Text.ToInt()+0xFF;

//AnsiString::IntToHex(addr,2)
Memo1ScreenPrint->Lines->Add("Mac Address Retrieved from PAC: "+
AnsiString(SPACPacketPtr->Source));
Memo1ScreenPrint->Lines->Add(AnsiString::IntToHex(ptrlsPacMacAddr->macAddr1,2)+
"-"+AnsiString::IntToHex(ptrlsPacMacAddr->macAddr2,2)+
"-"+AnsiString::IntToHex(ptrlsPacMacAddr->macAddr3,2)+
"-"+AnsiString::IntToHex(ptrlsPacMacAddr->macAddr4,2)+
"-"+AnsiString::IntToHex(ptrlsPacMacAddr->macAddr5,2)+
"-"+AnsiString::IntToHex(ptrlsPacMacAddr->macAddr6,2));
Memo1ScreenPrint->Lines->Add(" at: "+AnsiString(asctime(tblock)));

//AnsiString(text).AnsiPos("KeyWords")
lcTemp=AnsiString(lsStringBuffer).AnsiPos("OK");
if (lcTemp==0)
lcTemp=AnsiString(lsStringBuffer).AnsiPos("0");





//validate and decode ip address string
#include sys/types.h
#include sys/socket.h
#include arpa/inet.h



//To validate and decode ip address
std::string str3="";
size_t pos,posLast;
struct sockaddr_in sa;
char str[INET_ADDRSTRLEN];
int liRet;


//Check whether it's valid IP address
liRet=inet_pton(AF_INET,pszVal,&(sa.sin_addr));
if(liRet<0){
std::cout<<"Error: Only IpV4 address is supported"<}else if(liRet==0){
std::cout<<"Illegal IpV4 address string"<}else{
inet_ntop(AF_INET,&(sa.sin_addr),str,INET_ADDRSTRLEN);
std::cout<}


posLast=0;
pos=0;
//for(int j=0;j<4;j++){
// pos = std::string(pszVal).find(".",pos); // position of "." in str
// str3 = std::string(pszVal).substr (posLast,pos-posLast); // get from f"live" to the end
// from_string(lRealValue, str3, std::dec);
// std::cout<<"part "<// posLast=pos+1;
// pos++;
}