3.16 Calls to C++ from C or assembly language

You can call a C++ member function from C, assembly language, or embedded assembly.

Calling a C++ member function

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

struct T {
    T(int i) : t(i) { }
    int t;
    int f(int i);
};

// Definition of the C++ member function to be called from C.
int T::f(int i) { return i + t; }

// Declaration of the C function to be called from C++.
extern "C" int cfunc(T*);    

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

Defining the C function

The C function calls the C++ member function using its mangled name _ZN1T1fEi. The C function is defined as follows:

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)' */
}

Implementing the function in assembly language

To implement in assembly language the function that calls the C++ member function:

    PRESERVE8
    EXPORT cfunc
    AREA foo, CODE
    IMPORT  _ZN1T1fEi
cfunc
    STMFD   sp!,{r1, lr}     ; save lr for the call and preserve stack alignment
    MOV r1, #2               ; r0 already contains the object pointer
    BLX _ZN1T1fEi
    ADD r0, r0, r0, LSL #1   ; multiply by 3
    LDMFD sp!,{r1, pc}
    END

Implementing the function in embedded assembly

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

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*) {
    PRESERVE8
    STMFD sp!, {r1, lr}    ; save lr for the call and preserve stack alignment
    MOV r1, #2;            ; r0 already contains the object pointer
    BLX __cpp(T::f);
    ADD r0, r0, r0, LSL #1 ; multiply by 3
    LDMFD sp!, {r1, pc}
}
int f() {
    T t(5); // create an object of type T
    return asm_func(&t);
}
Non-ConfidentialPDF file icon PDF versionARM DUI0471M
Copyright © 2010-2016 ARM Limited or its affiliates. All rights reserved.