Alexander
Alexander

Reputation: 779

C linkage and c++ headers

I want to use some c++ classes in shared library with C linkage. And i got following problems.

If

#include <iostream>
extern "C"
{
 void f(){}
}

Compiles and links succesfully, but f() could not be found in resulting library.

If

extern "C"
{
#include <iostream>
 void f(){}
}

I got many compiler errors (just dont know how to correctly translate them in english, something about template with C linkage) on every occurence of C++ keyword "template" in iostream and included headers.

What should be done?

Upvotes: 1

Views: 1971

Answers (3)

James Kanze
James Kanze

Reputation: 153909

The first is correct; system headers (and most other headers as well) can only be included at global scope, outside any namespaces, classes, functions or linkage specification blocks. There are likely things in <iostream> that wouldn't be legal in an extern "C", and even if there weren't, the name mangling for extern "C" is almost certainly different from that of C++, and the library itself was surely compiled as extern "C++".

How did you define f? This could be a similar problem: if the source file compiles it as an extern "C++" function, then the name will be mangled differently than it was in the client files which compiled it as an extern "C" function.

The general policy here is to handle the headers and the function definitions/declarations in the same way you normally do, except that you ensure that the header can be included in both C and C++ sources, e.g.:

#if __cplusplus
extern "C" {
#endif
void f();
//  Other `extern "C"` functions...
#if __cplusplus
}
#endif

Then include this header in all files where the function f() is used, and in the file where it is defined.

Upvotes: 2

Catalin Serafimescu
Catalin Serafimescu

Reputation: 369

Use __declspec to export functions, classes, etc... Also: http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx

And this one is very good: http://www.flounder.com/ultimateheaderfile.htm

Upvotes: 0

filmor
filmor

Reputation: 32212

The first variant is correct. Only stuff that even exists in C can be declared in a extern "C" block, and templates and classes certainly don't belong in that category. You only have to make sure, that your function is also declared as extern "C" in the header if you are using a C++-compiler. This is often achieved by writing

#ifdef __cplusplus
// C++ declarations (for example classes or functions that have C++ objects
//                   as parameters)

extern "C"
{
#endif

// C declarations (for example your function f)

#ifdef __cplusplus
}
#endif

in the header.

Upvotes: 4

Related Questions