0

i'm using C++ Audio processing library for my Swift project from https://www.surina.net/soundtouch/sourcecode.html

I have also included those cpp file in my compile sources in Projects-targets-build phases.

When i try to import all of library header file in my bridging header

#import "SoundTouch.h"

i got error when try to compile it

Unknown type of name 'namespace' in STTypes.h
'stdexcept' file not found

i'm using namespace in my header file

namespace soundtouch { ... } 

i cannot use several standard library also like string

#include <stdexcept>
#include <string>

what i'm missing here?

calvin sugianto
  • 610
  • 7
  • 27
  • Swift *cannot* import C++: https://stackoverflow.com/questions/24042774/can-i-mix-swift-with-c-like-the-objective-c-mm-files, you need C wrapper: https://stackoverflow.com/questions/35229149/interacting-with-c-classes-from-swift. – Martin R Dec 13 '17 at 08:24
  • yes, i knew Swift cannot import C++, so i must import header files for the C++ wrapper right ? for example, i have SoundTouch.cpp , but i also have SoundTouch.h for the wrapper. So the next step is import SoundTouch.h file in my bridging header to make sure Swift can use it – calvin sugianto Dec 13 '17 at 08:32
  • 1
    If you import "SoundTouch.h" then "SoundTouch.h" must not (directly or indirectly) include *any* C++. It must be a pure C interface. – Martin R Dec 13 '17 at 08:39
  • You need to write a C interface that doesn't depend on "SoundTouch.h". – molbdnilo Dec 13 '17 at 08:42
  • so, in this example https://github.com/rspeyer/soundtouch i cannot use those header file directly to my bridging header? The next step is i must create a new objective C header file to wrap the header of my C++ file (SoundTouch.h) ? – calvin sugianto Dec 13 '17 at 08:45
  • @calvinsugianto im facing this issue again, have you found any solution yet? – Quang Thái Jan 07 '21 at 11:13

1 Answers1

2

Swift does not understand C++ even in header files. C does not have namespaces, so when the Swift compiler comes across the word namespace it's going to think the same as the C compiler would, which is that it is the name of a variable. That's not all though. Swift also won't understand other C++ keywords like class nor will it understand C++ style name mangling, even though it does its own name mangling, nor export "C" { ... }.

If you have a C++ header file that you want to import into Swift, you have to make sure all the C++ stuff is hidden with #ifdef __cplusplus just like if you are including the header in a C program. Also, all the function declarations will need to be extern "C" to disable name mangling.

You will need an alternate declaration for classes, you can use void* or I found an incomplete struct type works quite well and you'll need to create C wrapper functions to call functions defined in the class. Something like the following might work (I haven't tested it).

#if defined __cplusplus
extern "C" {
#endif

#if defiend __cplusplus

class Foo
{
    void bar(int c);
}
#endif
struct FooHandle;

void Foo_bar(struct FooHandle* foo, int c);

#if defined __cplusplus
}
#endif

And you'll need to define the shim function in a C++ file

#include MyHeader.h

void Foo_bar(struct FooHandle* foo, int c)
{
    ((Foo*) foo)->bar(c);
}

Apologies if I got the C++ wrong, I haven't used it seriously since 1998

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • so i must rewrite all of .h files from SoundTouch library ? that's around 14 files, and if they published a new version i must rewrite again for the new version? – calvin sugianto Dec 14 '17 at 04:47
  • @calvinsugianto Not necessarily. I would write a shim .h file with C functions for the operations you want to use. – JeremyP Dec 18 '17 at 11:21