

■C++クラスヘッダ→Test.h

[code]

    #ifndef TEST_H
    #define TEST_H
    #include "TestDef.h"
    void Test(TEST_STR& test_str);
    #endif     // TEST_H
    
[/code]

■C++デファインヘッダ→TestDef.h

[code]

    #ifndef TESTDEF_H
    #define TESTDEF_H
    struct TEST_STR {
        int a;
        int b;
    };
    #endif
    
[/code]

■C＋＋クラス→Test.cppをTest.mmにしました。

[code]

    #include "Test.h"
    #include "TestDef.h"
    
    void Test(TEST_STR& test_str)
    {
    }
    
[/code]

■Obje-c++ヘッダ→TestObj.h

[code]

    #ifndef TestObj_h
    #define TestObj_h
    
    #import <Foundation/Foundation.h>
    #import "TestDef.h"
    @interface TestObj : NSObject    
    - (void) test:(TEST_STR&)test ;
    @end
    
    #endif /* TestObj_h */
    
[/code]

■Obj-C++ソース→TestObj.mm

[code]

    #import <Foundation/Foundation.h>
    #import "TestObj.h"
    #import "Test.h"
    
    @implementation TestObj
    
    - (void) test:(TEST_STR&)a {
        Test(a);
    }
    
    @end
    
[/code]

■ブリッジファイルに`#import "TestObj.h"`を入れています。

このような感じなのですが、  
■Obje-c++ヘッダの下記の箇所で「Expected a type」が出てしまいます。

[code]

    - (void) test:(TEST_STR&)test ;
    
[/code]

上記エラーを検索すると、#import の追加がいるような記載があったため、そちらも追加してみましたが  
変わらず・・・  
XCODEからTEST_STRにジャンプもできたので参照できていると  
思うのですが何がおかしいのかさっぱりわかりません。  
ご助言いただけると助かります。


CC BY-SA 3.0
2016-03-05T04:59:11.540
22825
2016-11-17T05:02:47.337
2016-03-06T14:18:31.267
12732
12842
question
objective-c
Expected a typeがよく分からない


(ご自身で書かれているように「#import
の追加がいる」ような状態では各ファイルがどのようにimportされているかが重要になってきますので「C++クラスヘッダ」のようなファイルの概要の説明だけでなく、それらがどんなファイル名なのかも記載された方が良いでしょう。＞追記ありがとうございます。追記に関わる修正は下の方に。)

こちらでは、ご掲載のコードを以下のようなファイル名のファイルに置くと、コンパイルが通ってしまいます。

  * C++クラスヘッダ -> Test.h
  * C++デファインヘッダ -> TestDef.h
  * C＋＋クラス -> Test.cpp
  * Obje-c++ヘッダ -> TestObj.h
  * Obj-C++ソース -> TestObj.mm

「C＋＋クラス（mm拡張子に変更）」と書かれていますが、「Obj-C++ソース」の方の拡張子を.mmにしないと、そこからimportされているTestObj.h内ではC++データ型が使えなくなってしまいます。再度各ファイル名やimportを含むファイル内容を確認してみてください。

[追記]  
ご質問内の追記内容と私の上記内容を見比べると

  * C＋＋クラス -> Test.cppをTest.mmにしました。

という部分で違いがあるのですが、これは問題になりません。「C＋＋クラス」の中ではC++の機能しか使われていませんので、"C++"としてコンパイルしても"Objective-C++"としてコンパイルしても、結果は同じになります。

影響しているのはこちらのようですね。

  * ブリッジファイルに「#import "TestObj.h"」を入れています。

Xcodeでプロジェクトを作成された時にSwiftプロジェクトとして作成されたものにC++ファイルや、Objective-C++ファイルを追加されたのでしょうか。Swiftプロジェクトのビルドの過程でBridging-
Headerを参照する場合、その内容は(Objective-C++ではなく)Objective-
C用のヘッダとして解釈されます。従ってその中ではC++の参照型は型(type)としては認識されないものになるため、その際に"Expected a
type"になってしまっているのでしょう。

C++で書かれた関数の機能をSwiftから利用するためにObjective-C++でそのwrapperクラスを作成するといった場合、Swift側に読み込ませたいクラスの@interface部分ではC++の機能を使ってはいけません。  
例えば、Swift側には(参照型ではなく)ポインターでやりとりするというのが一つの手でしょう。

■Obj-c++ヘッダ→TestObj.h

[code]

    #ifndef TestObj_h
    #define TestObj_h
    
    #import <Foundation/Foundation.h>
    #import "TestDef.h"
    @interface TestObj : NSObject
    - (void) test:(TEST_STR*)test ;
    @end
    
    #endif /* TestObj_h */
    
[/code]

■Obj-C++ソース→TestObj.mm

[code]

    #import <Foundation/Foundation.h>
    #import "TestObj.h"
    #import "Test.h"
    
    @implementation TestObj
    
    - (void) test:(TEST_STR*)a {
        Test(*a);
    }
    
    @end
    
[/code]

上記のままでは、まだエラーが出るようですね。TEST_STR型の定義は"C++"としても"C"としても通るような書き方をする必要があります。

■C++デファインヘッダ→TestDef.h

[code]

    #ifndef TESTDEF_H
    #define TESTDEF_H
    typedef struct TEST_STR {
        int a;
        int b;
    } TEST_STR;
    #endif
    
[/code]

いかがでしょうか。何かありましたらまたご報告ください。


CC BY-SA 3.0
2016-03-05T07:39:23.480
22826
2016-03-05T08:36:29.787
2016-03-05T08:36:29.787
13972
13972
22825
answer