From: "Tim Van Holder" 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" 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(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 #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(m); } void myfoo_member(void) { MyFoo* object = reinterpret_cast(m); object->member(); } void delete_myfoo(void* m) { MyFoo* object = reinterpret_cast(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.