C 言語またはアセンブリ言語からの C++ 言語の呼び出し

この例では、非スタティックな非仮想 C++ メンバ関数を C から呼び出す方法を示します。

Example 25. C++ メンバ関数の呼び出し

struct T {
    T(int i) : t(i) { }
    int t;
    int f(int i);
};
int T::f(int i) { return i + t; }
// C から呼び出される C++ 関数の定義
extern "C" int cfunc(T*);
// C++ から呼び出される C 関数の宣言
int f() {
    T t(5);                    // T 型のオブジェクトを作成する
    return cfunc(&t);
}

関数の符号化された名前を参照するには、コンパイラのアセンブラ出力を使用して下さい。例えば、このコードがファイル test.cpp に含まれている場合は、以下のコマンドを入力します。

armcc -c --cpp --asm test.cpp

以下の内容を含むアセンブラファイル test.s が生成されます。

...
        AREA ||.text||, CODE, READONLY, ALIGN=2

_Z1fv PROC
        PUSH     {r3,lr}
        MOV      r0,#5
        STR      r0,[sp,#0]
        MOV      r0,sp
        BL       cfunc
        POP      {r3,pc}
        ENDP

_ZN1T1fEi PROC
        LDR      r0,[r0,#0]
        ADD      r0,r0,r1
        BX       lr
        ENDP
...

符号化された名前 _ZN1T1fEi を使用して、C 関数を定義します。

Example 26. C 関数の定義

struct T;
extern int _ZN1T1fEi(struct T*, int);
    /* 呼び出される C++ 関数の */
    /* 符号化された名前 */
int cfunc(struct T* t) {
/* C++ から呼び出される C 関数の定義*/
    return 3 * _ZN1T1fEi(t, 2);    /* like '3 * t->f(2)' */
}

アセンブリ言語で関数を実装するには、以下のように記述します。

Example 27. アセンブリ言語での関数の実装

    EXPORT cfunc
    AREA foo, CODE
    IMPORT  _ZN1T1fEi
cfunc
    STMFD   sp!,{lr}         ; R0 には既にオブジェクトポインタが含まれている
    MOV R1, #2
    BL _ZN1T1fEi
    ADD R0, R0, R0, LSL #1   ; 3 で乗算する
    LDMFD sp!,{pc}
    END

または、組み込みアセンブリを使用して、C++ メンバ関数およびアセンブリ言語の関数への呼び出しを実装できます。この例では、関数の参照に __cpp キーワードが使用されます。そのため、関数の符号化された名前を把握しておく必要はありません。

Example 28. 組み込みアセンブリでの関数の実装

struct T {
    T(int i) : t(i) { }
    int t;
    int f(int i);
};
int T::f(int i) { return i + t; }
// C++ から呼び出される asm 関数の定義
__asm int asm_func(T*) {
    STMFD sp!, {lr}
    MOV R1, #2;
    BL __cpp(T::f);
    ADD R0, R0, R0, LSL #1 ; 3 で乗算する
    LDMFD sp!, {pc}
}
int f() {
    T t(5); // T 型のオブジェクトを作成する
    return asm_func(&t);
}

Show/hide関連項目

Copyright © 2010-2011 ARM. All rights reserved.ARM DUI 0471EJ
Non-ConfidentialID081711