Forte C++ and extern "C"

Forte C++ and extern "C"

Post by j.. » Sat, 23 Jul 2005 10:15:59



I'm not sure why I'm running into this, I've done it a number of times
before.

I'm trying to compile a shared library that will be dynamically loaded
with dlopen(). The library implements a C++ class which is accessed by
means of a factory function declared extern "C". The compiler is
exiting with the error "Linkage specifications are allowed only at
file level."

In a small test program, the line referenced is

extern "C" Test *makeTest() {return new Test;}

The only thing above this is a line including Test.h which declares
the class.

I've probably been looking at this too long and can't see something
obvious. What's wrong with that line?

Joe

 
 
 

Forte C++ and extern "C"

Post by Seongbae Par » Sat, 23 Jul 2005 10:40:24



> I'm not sure why I'm running into this, I've done it a number of times
> before.

> I'm trying to compile a shared library that will be dynamically loaded
> with dlopen(). The library implements a C++ class which is accessed by
> means of a factory function declared extern "C". The compiler is
> exiting with the error "Linkage specifications are allowed only at
> file level."

> In a small test program, the line referenced is

> extern "C" Test *makeTest() {return new Test;}

> The only thing above this is a line including Test.h which declares
> the class.

> I've probably been looking at this too long and can't see something
> obvious. What's wrong with that line?

> Joe

My guess is that you have a code that looks like (after preprocessing):

class myclass {
  ...
  extern "C" Test *makeTest() { return newTest; }

Quote:}

This won't work.
A method can not be extern "C".
Only global functions can be extern "C".
--
#pragma ident "Seongbae Park, compiler, http://blogs.sun.com/seongbae/"

 
 
 

Forte C++ and extern "C"

Post by j.. » Sat, 23 Jul 2005 12:12:45




> > I'm not sure why I'm running into this, I've done it a number of times
> > before.

> > I'm trying to compile a shared library that will be dynamically
> > loaded with dlopen(). The library implements a C++ class which is
> > accessed by means of a factory function declared extern "C". The
> > compiler is exiting with the error "Linkage specifications are
> > allowed only at file level."

> > In a small test program, the line referenced is

> > extern "C" Test *makeTest() {return new Test;}

> > The only thing above this is a line including Test.h which declares
> > the class.

> > I've probably been looking at this too long and can't see something
> > obvious. What's wrong with that line?

> > Joe

> My guess is that you have a code that looks like (after preprocessing):

> class myclass {
>   ...
>   extern "C" Test *makeTest() { return newTest; }
> }

> This won't work.
> A method can not be extern "C".
> Only global functions can be extern "C".

No, it's a global free function. It's the interface between the
dlopen()'d library and the program that loads it. It's a factory
function that returns an instance of the class implemented by the
library.

Joe

 
 
 

Forte C++ and extern "C"

Post by Matt Atterbur » Sat, 23 Jul 2005 12:24:25



> I'm not sure why I'm running into this, I've done it a number of times
> before.

> I'm trying to compile a shared library that will be dynamically loaded
> with dlopen(). The library implements a C++ class which is accessed by
> means of a factory function declared extern "C". The compiler is
> exiting with the error "Linkage specifications are allowed only at
> file level."

> In a small test program, the line referenced is

> extern "C" Test *makeTest() {return new Test;}

> The only thing above this is a line including Test.h which declares
> the class.

> I've probably been looking at this too long and can't see something
> obvious. What's wrong with that line?

I've tried to reproduce your claimed problem using this code: test.C:
==============================================================================
struct Test { };
extern "C" Test* makeTest() { return new Test; }
==============================================================================
CC -c test.C compiles just fine.

We need more information.

 
 
 

Forte C++ and extern "C"

Post by j.. » Sat, 23 Jul 2005 12:48:48




> > I'm not sure why I'm running into this, I've done it a number of times
> > before.

> > I'm trying to compile a shared library that will be dynamically loaded
> > with dlopen(). The library implements a C++ class which is accessed by
> > means of a factory function declared extern "C". The compiler is
> > exiting with the error "Linkage specifications are allowed only at
> > file level."

> > In a small test program, the line referenced is

> > extern "C" Test *makeTest() {return new Test;}

> > The only thing above this is a line including Test.h which declares
> > the class.

> > I've probably been looking at this too long and can't see something
> > obvious. What's wrong with that line?

> I've tried to reproduce your claimed problem using this code: test.C:
> ===========================================================================
> struct Test { };
> extern "C" Test* makeTest() { return new Test; }
> ===========================================================================
> CC -c test.C compiles just fine.

> We need more information.

Here's Test.C

================================
#include "Test.h"

extern "C" Test *makeTest() {return new Test;}

Test::~Test()
{
  delete mClass1;
  delete mClass2;

Quote:}

void Test::f1()
{
  mClass1->id();

Quote:}

void Test::f2()
{
  mClass2->id();

Quote:}

Test.h
================================
#ifndef TEST_H
#define TEST_H

#include "Class1.h"
#include "Class2.h"

#include "Abstract.h"

class Test : public Abstract
{
public:
  Test() : mClass1(new Class1), mClass2(new Class2) {}
  ~Test();
  void f1();
  void f2();

private:
  Class1 *mClass1;
  Class1 *mClass2;

Quote:}

#endif

I could post the rest, but it's one-liner type stuff, if you want I
will

Test.C is compiled with

CC -c -Kpic Test.C

I can package the whole lot into a tarball and put it on a web site if
you want, but I'm really just trying to figure out why the compiler is
balking at the extern "C" declaration. It looks pretty straightforward
to me.

Joe

 
 
 

Forte C++ and extern "C"

Post by ckl.. » Sat, 23 Jul 2005 14:22:52


[snip]

Quote:

> class Test : public Abstract
> {
> public:
>   Test() : mClass1(new Class1), mClass2(new Class2) {}
>   ~Test();
>   void f1();
>   void f2();

> private:
>   Class1 *mClass1;
>   Class1 *mClass2;
> }

Add the missing semicolon above and things will work (they did for me).
OTOH,
you should really post self-contained compilable code to allow people
to easier reproduce your problems.

Quote:

> #endif

[snip]
 
 
 

Forte C++ and extern "C"

Post by Seongbae Par » Sat, 23 Jul 2005 16:30:11


...

Quote:> I could post the rest, but it's one-liner type stuff, if you want I
> will

> Test.C is compiled with

> CC -c -Kpic Test.C

> I can package the whole lot into a tarball and put it on a web site if
> you want, but I'm really just trying to figure out why the compiler is
> balking at the extern "C" declaration. It looks pretty straightforward
> to me.

Your code above wasn't complete.
However, it seems that you're missing ; after the class declaration
which is causing the compiler to issue the misleading error message.

# cat t1.cc
class Abstract { };
class Test : public Abstract { }
extern "C" Test *makeTest() { return new Test; }
# CC -c t1.cc
"t1.cc", line 3: Error: Linkage specifications are allowed only at file level.
"t1.cc", line 3: Error: "," expected instead of "*".
"t1.cc", line 3: Error: A declaration was expected instead of "}".
3 Error(s) detected.
# cat t2.cc
class Abstract { };
class Test : public Abstract { };
extern "C" Test *makeTest() { return new Test; }
# CC -c t2.cc
#

Note that t2.cc has ";" at the end of the line 2, which is missing in line 1.
The some error messages from the compiler are best-effort only.
Especially missing } or ; or ) tends to cause mysterious error messages
not where those are missing but somewhere later....
--
#pragma ident "Seongbae Park, compiler, http://blogs.sun.com/seongbae/"

 
 
 

Forte C++ and extern "C"

Post by j.. » Sat, 23 Jul 2005 22:10:30



> Your code above wasn't complete.  However, it seems that you're
> missing ; after the class declaration which is causing the compiler
> to issue the misleading error message.

Ahh, I knew I'd been looking at it too long. Thanks

Joe