Wednesday, March 21, 2012

C Call C++


From [3]
 // C++ code:
 extern "C" void f(int);
 void f(int i){
  // ...
 /* C code: */
 void f(int);
 void cc(int 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){
  /* ... */

From [1]

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


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

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

   printf("return of C++ Wilma: %d\n",lc);


// 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){
  return fred;

//Provide access of C++ methods from C code.
unsigned char Cplusplus_CallbackFunction_Wilma(int a, Fred* fred){


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

 #ifdef __cplusplus
   class Fred {
     void wilma(int);
     int a_;
   typedef struct Fred  Fred;


 #ifdef __cplusplus
 extern "C" {

 #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);
   extern void c_function();        /* K&R style */
   extern Fred* cplusplus_callback_function();

 #ifdef __cplusplus

 #endif /*FRED_H*/

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

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


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

 $(CP) -c $(CFLAGS) $< -o $@ $(INCL)

 $(C) -c $(CFLAGS) $< -o $@ $(INCL)

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


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] 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.

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