11

How should I call a C++ function (no classes involved) from a Swift file? I tried this:

In someCFunction.c:

void someCFunction() {
    printf("Inside the C function\n");
}

void aWrapper() {
    someCplusplusFunction();
}

In someCpluplusfunction.cpp:

void someCplusplusFunction() {
    printf("Inside the C++ function");
}

In main.swift:

someCFunction();
aWrapper();

In Bridging-Header.h:

#import "someCFunction.h"
#import "someCplusplusFunction.h"

I found this answer very informative, but still I cannot make it work. Could you point me in the right direction?

Thanks!

Community
  • 1
  • 1
popisar
  • 379
  • 2
  • 3
  • 15

1 Answers1

14

What does the header look like?

If you want to explicitly set the linking type for C-compatible functions in C++, you need to tell the C++ compiler so:

// cHeader.h

extern "C" {
    void someCplusplusFunction();
    void someCFunction();
    void aWrapper();
}

Note that this isn't valid C code, so you'd need to wrap the extern "C" declarations in preprocessor macros.

On OS X and iOS, you can use __BEGIN_DECLS and __END_DECLS around code you want linked as C code when compiling C++ sources, and you don't need to worry about using other preprocessor trickery for it to be valid C code.

As such, it would look like:

// cHeader.h

__BEGIN_DECLS
void someCplusplusFunction();
void someCFunction();
void aWrapper();
__END_DECLS

EDIT: As ephemer mentioned, you can use the following preprocessor macros:

// cHeader.h

#ifdef __cplusplus 
extern "C" { 
#endif 
void someCplusplusFunction();
void someCFunction();
void aWrapper();
#ifdef __cplusplus 
}
#endif
MaddTheSane
  • 2,981
  • 24
  • 27
  • Thank you! It works perfectly for this example. Xcode still doesn't want to link the real project, but I'll continue the investigations. – popisar Nov 08 '14 at 12:38
  • I found the problem with the real project: I am trying to pass a string as an argument to the C++ function. According to what I read, a Swift **String** should be casted automatically to a C **const char\***, but I suppose I am missing something... – popisar Nov 09 '14 at 09:57
  • If only I coded what I preach... In my code, I mixed up **const char\*** and **char\***. To resume: @MaddTheSame gave the good answer. Nothing to add, but a thanks :-) – popisar Nov 09 '14 at 15:11
  • 2
    "You'd need to wrap the `extern "C"` declarations in preprocessor macros", specifically: `#ifdef __cplusplus extern "C" { #endif ` your C function definitions here... `#ifdef __cplusplus } #endif`. I can't put line breaks in a comment, but you'd need line breaks before and after the "extern C {" and the "}" – ephemer May 11 '15 at 09:11
  • Thanks mate :) @MaddTheSane – Piyush Chauhan Jul 17 '16 at 09:50