简体   繁体   中英

Swift Bridging header from C++ is not Working

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM