www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/01/12/06:36:42

From: "Tim Van Holder" <tim DOT vanholder AT falconsoft DOT be>
Subject: Re: Calling C++ functions from C (or using Bison with C++)
Newsgroups: comp.os.msdos.djgpp
Organization: Falcon Software NV
Message-ID: <20010112.122527.2027907669.15238@falconsoft.be>
User-Agent: Pan/0.9.2 (Unix)
X-No-Productlinks: Yes
Lines: 174
Date: Fri, 12 Jan 2001 11:26:07 GMT
NNTP-Posting-Host: 195.207.71.6
X-Complaints-To: abuse AT Belgium DOT EU DOT net
X-Trace: nreader1.kpnqwest.net 979298767 195.207.71.6 (Fri, 12 Jan 2001 12:26:07 MET)
NNTP-Posting-Date: Fri, 12 Jan 2001 12:26:07 MET
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

In a burst of inspiration, "Nimrod A. Abing"
<n_abing AT ns DOT roxas-online DOT net DOT ph> wrote this on
<3 DOT 0 DOT 1 DOT 32 DOT 20010112084816 DOT 006bc314 AT wingate>:

> parser. I intended to call C++ functions from within the parser
> rule-actions until I realized that this would be a problem because the
> parser is in C.
If it just regular functions you're calling, and not class members, it
should suffice to use 'extern "C"' in front of the prototypes of those
functions. This also makes it impossible to overload those functions
though.

===
[test.h]

extern "C" void* MyCPlusPlusFunc(int x);

[test.cc]

extern "C"
void*
MyCPlusPlusFunc(int x)
{
void* ret = 0;
  try {
     ret = reinterpret_cast<void*>(new MyFooStructure);
  }
  catch(...) {
    return 0;
  }
}

[foo.y]
%{
#include "test.h"
%}

...

rule: element-1 element-2 { $$ = MyCplusPlusFunc(); } ;
===

Alternatively, you could create a C wrapper for each C++ function you
use.
This has the advantage that you can use overloaded C++ functions (you
just need to make the names of the wrappers different). And if you don't
mind screwing with casts, you could even use class members, although I
certainly don't recommend it (and I'm not even sure the compiler will
allow you to do such evil casts (might need to use C-style casts instead
of reinterpret_cast)).

===
[test.h]

class MyFoo {
public:
  MyFoo() {}
  ~MyFoo() {}
  void member(void);
};

unsigned long
MyIntegralFunc(unsigned long)
{
  ...
}

unsigned int
MyIntegralFunc(unsigned int)
{
  ...
}

unsigned short
MyIntegralFunc(unsigned short)
{
  ...
}

[testwrap.h]

#ifdef __cplusplus
extern "C" {
#endif

void* new_myfoo(void);
void myfoo_member(void*);
void delete_myfoo(void*);

unsigned long mylongfunc(unsigned long);
unsigned int myintfunc(unsigned int);
unsigned short myshortfunc(unsigned short);

#ifdef __cplusplus
}
#endif

[testwrap.cc]

#include <new>
#include "test.h"
#include "testwrap.h"

unsigned long
mylongfunc(unsigned long ul)
{
  return MyIntegralFunc(ul);
}

unsigned int
myintfunc(unsigned int ui)
{
  return MyIntegralFunc(ui);
}

unsigned short
myshortfunc(unsigned short us)
{
  return MyIntegralFunc(us);
}

// Here there be dragons

void*
new_myfoo(void)
{
MyFoo* m = new (nothrow) MyFoo;
    return reinterpret_cast<void*>(m);
}

void
myfoo_member(void)
{
MyFoo* object = reinterpret_cast<MyFoo*>(m);
  object->member();
}

void
delete_myfoo(void* m)
{
MyFoo* object = reinterpret_cast<MyFoo*>(m);
    delete object;
}

[foo.y]
%{
#include "test.h"
%}

...

sub-rule: element-1 element-2 { $$ = new_myfoo(); mylongfunc(666); } ;

foo: sub-rule
       {
          myshortfunc(7);
          myfoo_member($1);
          delete_myfoo($1);
          myintfunc(13);
       }

===

A final alternative would be to edit bison.simple/bison.hairy to be a
valid C++ source file. Then you can simply run bison to generate the
code, and use gcc (-x c++) to compile it as C++. You could even try
turning the skeletons into an implementation of some class (and create a
generic header (like FlexLexer.h) for applications to use).

-- 
Tim Van Holder - Falcon Software N.V.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
This message was posted using plain text. I do not endorse any
products or services that may be hyperlinked to this message.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019