extern "C" causing an error "expected '(' before string constant" [duplicate] - c++

This question already has answers here:
What is the effect of extern "C" in C++?
(17 answers)
Including C headers inside a C++ program
(5 answers)
Closed 5 years ago.
file1.c
int add(int a, int b)
{
return (a+b);
}
file2.cpp
void main()
{
int c;
c = add(1,2);
}
h1.h
extern "C" {
#include "stdio.h"
int add(int a,int b);
}
Case 1:
when i include h1.h in file1.c file then gcc compiler throw an error "expected '(' before string constant".
case 2:
when I include h1.h in file2.cpp file compilation work successfully
Question:
1) Does it mean that I can not include header file in C with extern "C" function in it??
2) Can I include header within extern"C" like shown below
extern "C" {
#include "abc.h"
#include "...h"
}
3) Can I put c++ functions definitions in header file with extern "C" so that i can call it in C file?
for example
a.cpp ( cpp file)
void test()
{
std::printf("this is a test function");
}
a.h (header file)
extern "C" {
void test();
}
b_c.c ( c file)
#include "a.h"
void main()
{
test();
}

Write a.h like this:
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
int add(int a,int b);
#ifdef __cplusplus
}
#endif
This way you can declare multiple functions - there is no need to prefix each one with extern C.
As others mentioned: extern C is a C++ thing, so it needs to "disappear" when seen by C compiler.

Since extern "C" is not understood by a C-compiler you need to create a header that can both be included in a C and C++ file.
E.g.
#ifdef __cplusplus
extern "C" int foo(int,int);
#else
int foo(int,int);
#endif

Related

Unresolved symbol for inline function

Please consider the following code:
Test2.h:
#ifndef ABCD
#define ABCD
#ifdef __cplusplus
extern "C" {
#endif
void Foo();
#ifdef __cplusplus
}
#endif
#endif // ABCD
Test2.cpp
#include "StdAfx.h"
#include "Test2.h"
inline void Foo()
{
}
Test.cpp:
#include "stdafx.h"
#include "Test2.h"
int _tmain(int argc, _TCHAR* argv[])
{
Foo();
return 0;
}
When I compile this code I get LNK2019 error (Unresolved external symbol _Foo).
I can solve it in two ways.
Remove the inline keyword.
Add extern to the function declaration.
Assuming I want this function inline, why do I have to add extern to the declaration?
I use VS2008.
Thanks.
C++11 Standard Paragraph 3.2.3:
An inline function shall be defined in every translation unit in which it is odr-used.
You have 2 translation units, first made from Test2.cpp...:
// ... code expanded from including "StdAfx.h"
extern "C" { void Foo(); }
inline void Foo() { }
...and second made from Test.cpp:
// ... code expanded from including "StdAfx.h"
extern "C" { void Foo(); }
int _tmain(int argc, _TCHAR* argv[])
{
Foo();
return 0;
}
In the second TU, the definition of Foo is missing.
Why don't you simply put the definition of Foo into the header file? Compiler cannot inline its code if it does not see it.

How to define string parameters in C++ header file - Bridged with Swift?

I have a Xcode project with Swift and C++ (with bridging header), and I am trying to create a function in C++ with 2 string parameters, and returning an array of integers back to Swift:
.cpp file:
int* example(string one, string two)
{
int test[3] = {7,2,3};
return test;
}
.h file:
#if __cplusplus
extern "C" {
#endif
int* example(string one, string two); //ERROR HERE
#ifdef __cplusplus
}
#endif
I am getting this error (in the .h file):
Unknown type name 'string'
I tried to include the string header file to the header, but then I get the error (I also had to add std:: before the string):
New function declaration:
int* example(std::string one, std::string two);
Error (at the first std::)
Expected ')'
I am really losing my patience here, what am I doing wrong?
You can't use class types in extern "C" declaration. You can introduce the following trick:
header:
#if __cplusplus
extern "C" {
#endif
int* example(void *one, void *two);
#ifdef __cplusplus
}
#endif
source: (.cpp assumed)
#include <string>
using namespace std;
extern "C" {
int* example(void *one, void *two)
{
string &a = *reinterpret_cast<string*>(one);
string &b = *reinterpret_cast<string*>(two);
...
}
}
You must pass strings by ptr.

can I use extern "C" { headerfile of c }

Instead of writing each function in " extern "C" {} ", can I write entire header file inside that block.
extern "C"
{
#include "myCfile.h"
}
I have tried this but Its not working at all, why it is not working ?
if we have to use 100 C functions in a c++ project, do we need provide all the functions in a
extern block, is there any other simple way ?
Ex:
extern "C"
{
void fun1();
void fun2();
void fun3();
void fun4();
void fun5();
.
.
.
.
fun100();
}
Is there any other simple way, like extern "C" { myCfunctions.h } ???
#include simply includes the specified header at the location of the #include. Whether it's valid depends on what "myCfile.h" contains. In particular, including any standard library headers in such a context is not valid, and may well break on commonly used implementations.
The usual way to handle this is to make the header itself safe to use from C++. A C-only header might contain
#ifndef H_MYCFILE
#define H_MYCFILE
#include <stddef.h>
void mycfunc1(void);
void mycfunc2(int i);
void mycfunc3(size_t s);
#endif
Adapting this to make it safe to use from C++:
#ifndef H_MYCFILE
#define H_MYCFILE
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void mycfunc1(void);
void mycfunc2(int i);
void mycfunc3(size_t s);
#ifdef __cplusplus
}
#endif
#endif
With such a header, you wouldn't be able to safely put the entire header in an extern "C" block. However, that header itself can make sure not to put #include <stddef.h> in an extern "C" block, but still to put all function declarations in a single extern "C" block, avoiding having to repeat it for each one.
You are doing something wrong.
Because
extern "C" { myCfunctions.h }
should work. See below sample program.
Lets go by example code.
ctest1.c
#include<stdio.h>
void ctest1(int *i)
{
printf("This is from ctest1\n"); // output of this is missing
*i=15;
return;
}
ctest2.c
#include<stdio.h>
void ctest2(int *i)
{
printf("This is from ctest2\n"); // output of this is missing
*i=100;
return;
}
ctest.h
void ctest1(int *);
void ctest2(int *);
Now lets make c library from that
gcc -Wall -c ctest1.c ctest2.c
ar -cvq libctest.a ctest1.o ctest2.o
Now lets make cpp based file which will use this c apis
prog.cpp
#include <iostream>
extern "C" {
#include"ctest.h"
}
using namespace std;
int main()
{
int x;
ctest1(&x);
std::cout << "Value is" << x;
ctest2(&x);
std::cout << "Value is" << x;
}
Now lets compile this c++ program with C library
g++ prog.cpp libctest.a
Output is :
Value is15Value is100

extern keyword in C on more functions

I would like to include one header file in both C and C++, and I have a function defined in C code and few functions defined in external library.
#if defined(__cplusplus)
extern "C" {
#endif
void func0();
#if !defined(__cplusplus)
extern {
#endif
void func1();
int func2(int);
} /* extern */
This code produces compilation error when compiled from C source file
error C2059: syntax error : '{'
Is it possible to fix syntax error directly or I have to use some macros?
EXTERNCPP void func0();
EXTERNC void func1();
EXTERNC int func2(int);
Edit 1:
I do not ask about
Effects of the extern keyword on C functions, I just ask if it is possible to fix syntax in easy way. If it is not possible, i could still remove it completely for C part
Edit 2:
To clarify what I want to get. If header is included
from C++:
extern "C" void func0();
extern "C" void func1();
extern "C" int func2(int);
from C:
void func0();
extern void func1();
extern int func2(int);
extern { is not needed.You need to remove it:-
#if defined(__cplusplus)
extern "C" {
#endif
void func0();
#if !defined(__cplusplus)
#endif
void func1();
int func2(int);
#if defined(__cplusplus)
}
#endif
You can simply omit the extern { line when compiling as a C header.
#if defined(__cplusplus)
extern "C" {
void func0();
#endif
#if !defined(__cplusplus)
void func1();
int func2(int);
#endif
#if defined(__cplusplus)
}
#endif
* [EDIT] answering your last edit:
void func0(); /* included in both versions */
#if defined(__cplusplus)
extern "C" {
void func1();
int func2(int);
#endif
#if !defined(__cplusplus)
extern void func1();
extern int func2(int);
#endif
#if defined(__cplusplus)
}
#endif
If you want to use func0 as extern in C:
#if defined(__cplusplus)
extern "C" {
void func0();
void func1();
int func2(int);
#endif
/* C block */
#if !defined(__cplusplus)
extern void func0();
extern void func1();
extern int func2(int);
#endif
#if defined(__cplusplus)
}
#endif
If you don't want to use it at all (from C) remove it from the C block

Adding namespaces to C++ implementations that have a C header

We have a large project with C and C++ code.
For every C++ implementation, apart from the C++ header, we usually have provide a C-header to allow functionality to be available for .c files, also.
So, most of our files look like so:
foo.hpp:
class C {
int foo();
};
foo.h:
#ifdef __cplusplus
extern "C" {
typedef struct C C; // forward declarations
#else
class C;
#endif
int foo( C* ); // simply exposes a member function
C* utility_function( C* ); // some functionality *not* in foo.hpp
#ifdef __cplusplus
}
#endif
foo.cpp:
int C::foo() { /* implementation here...*/ }
extern "C"
int foo( C *p ) { return p->foo(); }
extern "C"
C* utility_function ( C* ) { /* implementation here...*/ }
QUESTION:
Suppose I wanted to add a namespace to the class like so:
foo.hpp:
namespace NS {
class C {
int foo();
};
}
what is the best scheme to follow in the C-headers?
I have considered a few options, but I'm looking for the most elegant, safe and easy to read. Is there a standard way you use?
Here are the options I've considered:
(I've ommitted the extern "C" constructs for simplicity)
Option 1: fool the compiler by adding some code in each header:
foo.h
#ifdef __cplusplus
namespace NS { class C; } // forward declaration for C++
typedef NS::C NS_C;
#else
struct NS_C; // forward declaration for C
#endif
int foo( NS_C* );
NS_C* utility_function( NS_C* );
this adds some complexity to the header, but keeps the implementations unchanged.
Option 2: Wrap the namespace with a C-struct:
Keeps the header simple but makes the implementation more complex:
foo.h
struct NS_C; // forward declaration of wrapper (both for C++ and C)
int foo( NS_C* );
NS_C* utility_function( NS_C* );
foo.cpp
namespace NS {
int C::foo() { /* same code here */ }
}
struct NS_C { /* the wrapper */
NS::C *ptr;
};
extern "C"
int foo( NS_C *p ) { return p->ptr->foo(); }
extern "C"
NS_C *utility_function( NS_C *src )
{
NS_C *out = malloc( sizeof( NS_C ) ); // one extra malloc for the wrapper here...
out->ptr = new NS::C( src->ptr );
...
}
are these the only schemes? Are there any hidden disadvantages in any of these?
I find it easier to factor code in a way so that foo.h only contains the bare minimum of C++ specifics while foo.hpp takes care of the gritty bits.
The file foo.h contains the C API and should not be included directly from C++ code:
#ifndef NS_FOO_H_
#define NS_FOO_H_
// an incomplete structure type substitutes for NS::C in C contexts
#ifndef __cplusplus
typedef struct NS_C NS_C;
#endif
NS_C *NS_C_new(void);
void NS_C_hello(NS_C *c);
#endif
The file foo.hpp contains the actual C++ API and takes care of including foo.h into C++ files:
#ifndef NS_FOO_HPP_
#define NS_FOO_HPP_
namespace NS {
class C {
public:
C();
void hello();
};
}
// use the real declaration instead of the substitute
typedef NS::C NS_C;
extern "C" {
#include "foo.h"
}
#endif
The implementation file foo.cpp is written in C++ and thus includes foo.hpp, which also pulls in foo.h:
#include "foo.hpp"
#include <cstdio>
using namespace NS;
C::C() {}
void C::hello() {
std::puts("hello world");
}
C *NS_C_new() {
return new C();
}
void NS_C_hello(C *c) {
c->hello();
}
If you do not want to make the C API available to C++ code, you could move the relevant parts from foo.hpp to foo.cpp.
As an example for use of the C API a basic file main.c:
#include "foo.h"
int main(void)
{
NS_C *c = NS_C_new();
NS_C_hello(c);
return 0;
}
This example has been tested with the MinGW edition of gcc 4.6.1 using the following compiler flags:
g++ -std=c++98 -pedantic -Wall -Wextra -c foo.cpp
gcc -std=c99 -pedantic -Wall -Wextra -c main.c
g++ -o hello foo.o main.o
The code assumes that the types NS::C * and struct NS_C * have compatible representation and alignment requirements, which should be the case virtually everywhere, but as far as I know is not guaranteed by the C++ standard (feel free to correct me if I'm wrong here).
From a C language perspective, the code actually invokes undefined behaviour as you're technically calling a function through an expression of incompatible type, but that's the price for interoperability without wrapper structures and pointer casts:
As C doesn't know how to deal with C++ class pointers, the portable solution would be to use void *, which you should probably wrap in a structure to get back some level of type safety:
typedef struct { void *ref; } NS_C_Handle;
This would add unnecessary boilerplate on platforms with uniform pointer representation:
NS_C_Handle NS_C_new() {
NS_C_Handle handle = { new C() };
return handle;
}
void NS_C_hello(NS_C_Handle handle) {
C *c = static_cast<C *>(handle.ref);
c->hello();
}
On the other hand, it would get rid of the #ifndef __cplusplus in foo.h, so it's actually not that bad, and if you care about protability, I'd say go for it.
I don't fully understand what you're trying to do, but this may help:
If you want it still accessible by C then do this:
void foo();
namespace ns {
using ::foo;
}
Or use a macro:
#ifdef __cplusplus
#define NS_START(n) namespace n {
#define NS_END }
#else
#define NS_START(n)
#define NS_END
#endif
NS_START(ns)
void foo();
NS_END
Your header is all messed up.
You probably want something more like:
struct C;
#ifdef __cplusplus
extern "C" {
#else
typedef struct C C;
#endif
/* ... */
#ifdef __cplusplus
}
#endif