Reputation: 779
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
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
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
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