Calls to C++ from C or assembly language

This example shows how to call a non static, non virtual C++ member function from C.

Example 25. Calling a C++ member function

struct T {
    T(int i) : t(i) { }
    int t;
    int f(int i);
};
int T::f(int i) { return i + t; }   
// Definition of the C++ function to be called from C.
extern "C" int cfunc(T*);    
// Declaration of the C function to be called from C++.
int f() {
    T t(5);                    // create an object of type T
    return cfunc(&t);
}

Use the assembler output from the compiler to locate the mangled name of the function. For example, if this code is in the file test.cpp, enter the command:

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

This produces the assembler file test.s containing:

...
        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
...

You define the C function using the mangled name _ZN1T1fEi as follows:

Example 26. Defining the C function

struct T;
extern int _ZN1T1fEi(struct T*, int);
    /* the mangled name of the C++ */
    /* function to be called */
int cfunc(struct T* t) {   
/* Definition of the C function to be called from C++. */
    return 3 * _ZN1T1fEi(t, 2);    /* like '3 * t->f(2)' */
}

To implement the function in assembly language:

Example 27. Implementing the function in assembly language

    EXPORT cfunc
    AREA foo, CODE
    IMPORT  _ZN1T1fEi
cfunc
    STMFD   sp!,{lr}         ; R0 already contains the object pointer
    MOV R1, #2
    BL _ZN1T1fEi
    ADD R0, R0, R0, LSL #1   ; multiply by 3
    LDMFD sp!,{pc}
    END

Alternatively, you can implement the call to a C++ member function and the function in assembly language using embedded assembly. In this example, use the __cpp keyword to reference the function. Therefore, you do not have to know the mangled name of the function.

Example 28. Implementing the function in embedded assembly

struct T {
    T(int i) : t(i) { }
    int t;
    int f(int i);
};
int T::f(int i) { return i + t; }
// Definition of asm function called from C++
__asm int asm_func(T*) {
    STMFD sp!, {lr}
    MOV R1, #2;
    BL __cpp(T::f);
    ADD R0, R0, R0, LSL #1 ; multiply by 3
    LDMFD sp!, {pc}
}
int f() {
    T t(5); // create an object of type T
    return asm_func(&t);
}

Show/hideSee also

Copyright © 2010-2012 ARM. All rights reserved.ARM DUI 0471G
Non-ConfidentialID021412