My need was that I want to call a swift function from my cpp code. I have tried Using Bridging method for this purpose. When I try to call a swift from c it is working. Since C and C++ are similar, I used the same logic in C++ ,but it is not working.
Compilation of this CPP code gives error like Undefined symbol: sayHello() .
My c and c++ sample code is like this ,
CToSwift-Bridging-Header.h
void callCpp();
extern void sayHello();
main.c/.cpp
#include <stdio.h>
#include "CToSwift-Bridging-Header.h"
int main(int argc, const char * argv[]) {
printf("Hello, Main!\n");
callCpp();
return 0;
}
void callCpp() {
printf("CPP: Hi This is C\n");
printf("CPP: Swift say hello to everyone !\n");
sayHello();
printf("CPP: Nice! ");
}
Testswift.swift
import Foundation
@_cdecl("sayHello")
func sayHello()
{
print ("Swift:Hello , Welcome to Swift")
}
After reading some available documentation for this concept, I understand Swift (Obj c) and C++ is not directly related since both are evolved from C on different manner.
But my queries are
1] Is something else which I am missing in this Bridging header method to call a swift function from a C++ Code?
2] Is there any other Method to achieve my goal ?
3] Can we able to pass the swift code as a library or dll when compiling C++ ?
This looks like a name mangling issue.
C++ adds information to the name of each function that encodes the parameter and return types so that overloading with different parameter types works.
The normal trick to include C headers (which your bridging header is effectively) is an extern "C" { ... }
If I remember correctly from my C++ programming days 20 years ago, it should go like this:
#ifdef __cplusplus
void callCpp();
extern "C" {
#endif
extern void sayHello();
#ifdef __cplusplus
}
#endif
Everything inside the extern "C" { ... }
will be treated by the C++ compiler as straight C and so no name mangling will be done. The compiler will remember this if it encounters the function implementation inside C++ code and will apply no name mangling to it either so the extern declaration and the implementation have matching names.
The ifdef
s stop C (and Swift) from seeing the C++ extern "C" { ... }
.
On the assumption that you want callCpp()
to use C++ conventions, I've put it outside the extern "C"
but inside the ifdef
so it is not visible to C and Swift programs.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.