Function Name Mangling in C++ and Interfacing with ILE RPG

Technote (troubleshooting)


Problem(Abstract)

The C++ compiler performs name mangling. For example, it adds to the name of each C++ function a suffix encoding the parameter list, the return value of the function, and scoping information.

Resolving the problem

The C++ compiler performs name mangling. For example, it adds to the name of each C++ function a suffix encoding the parameter list, the return value of the function, and scoping information. The purpose of name mangling is to allow for function overloading. This means that multiple functions can have the same name as long as the compiler can tell them apart based on their parameter lists and return values. This is explained in the manual WebSphere Development Studio C/C++ Language Reference. As a practical example, consider the following C++ source:

#include <iostream>                  
using namespace std;                  
void print(int i){                    
cout << "Here is int "   << i << endl;
}                                    
void print(double f){                
cout << "Here is float " << f << endl;
}                                    
void print(char* c){                  
cout << "Here is char* " << c << endl;
}                                    
int main(){                          
print(10);                            
print(10.10);                        
print("ten");                        
}


Function "print" is overloaded because of the multiple versions defined. The compiler accepts all versions and distinguishes among them based on their parameter lists (note that the return value of all three versions is void, but the parameter lists are all different). The mangled names of these functions are unique. This can be verified by compiling the above source using the CRTCPPMOD command and then using the DSPMOD MODULE(modulename) DETAIL(*PROCLIST) command. The output shows the following:


                                Procedure list:                          
                                                                         
 Procedure Name                                  Procedure Type     ARGOPT
 print__Fi                                       REGULAR            *NO
 print__Fd                                       REGULAR            *NO
 print__FPc                                      REGULAR            *NO
 .......


For the purposes of importing/exporting function names, C++ uses these mangled names. In C++, function definitions in exporting modules and prototypes in importing modules refer to the non-mangled name(s) (in this case, "print"). It is also important to note that C++ function names, whether mangled or not, are case sensitive. For information on how to correlate the mangled names of user-defined functions to the original names as declared, see source member DEMANGLE, file H, library QSYSINC.

These considerations are especially important when interfacing C++ with other languages. In particular, this document demonstrates how to handle name-mangling when interfacing C++ with ILE RPG. RPG prototypes for import and export must refer to the mangled name(s) exactly as generated by the C++ compiler. To see all mangled names imported/exported for a C++ module, compile the source code using the CRTCPPMOD command. Then, run the DSPMOD MODULE(modulename) DETAIL(*IMPORT *EXPORT) command. Note that the import screen from this command will also contain some unrelated default imports, for example:


                         Imported (unresolved) symbols:                        
                                                                               
 Symbol Name                                      Symbol Type        ARGOPT    
 _C_exception_router                              PROCEDURE          *UNKNOWN  
 __ls__7ostreamFd                                 PROCEDURE          *NO        
 __ls__7ostreamFPCc                               PROCEDURE          *NO        
 flush__7ostreamFv                                PROCEDURE          *NO        
 complicated_put__7ostreamFc                      PROCEDURE          *NO        
 Q LE leDefaultEh                                 PROCEDURE          *UNKNOWN  
 _C_SIGABRT_ctl_action                            DATA                          
 _C_SIGFPE_ctl_action                             DATA                          
 _C_SIGILL_ctl_action                             DATA                          
 _C_SIGINT_ctl_action                             DATA                          
 _C_SIGSEGV_ctl_action                            DATA                          
 _C_SIGTERM_ctl_action                            DATA                          
 _C_SIGUSR1_ctl_action                            DATA                          
 _C_SIGUSR2_ctl_action                            DATA                          
 _C_SIGIO_ctl_action                              DATA                          
 _C_SIGALL_ctl_action                             DATA                          
 _C_SIGOTHER_ctl_action                           DATA                          
 cout                                             DATA



For C++ and ILE RPG to interface correctly, do the following:

1. Compile each C++ source member first using the CRTCPPMOD command.
2. Run CL command DSPMOD MODULE(modulename) DETAIL(*IMPORT *EXPORT). Note the mangled names of the user-defined functions imported and exported.
3. Re-edit the ILE RPG source. On each prototype interfacing with C++, add keyword EXTPROC('.......'), where ....... is the mangled name imported by or exported from the C++ module. The name must be enclosed in single quotes and is case sensitive.
4. Compile each ILE RPG source member using the CRTRPGMOD command.
5. Bind the modules using the CRTPGM command to create the program.
The following code samples illustrate our interfacing technique. The ILE RPG source is already re-edited per Steps 1, 2, 3 (the EXTPROC keywords added during re-editing are highlighted). To create the program, compile the RPG module (which is the entry point for the program), compile the C++ module, and bind the two modules together using the CRTPGM command.

ILE RPG Source


*                                                                        
 * This module contains the program entry point and works in conjunction  
 * with C++ module MOD_CPP.                                                
 *                                                                        
 *                                                                        
 * Definition for double-precision fields.                                
 *                                                                        
D StdDouble       S              8F                                        
 *                                                                        
 * Symbolic name for the constant pi.                                      
 *                                                                        
D pi              C                   const(3.1415926535897932384626433833)
 *                                                                        
 * rpgtocpp adds two double-precision numbers, displays the result,        
 * then returns the result to the caller.                                  
 * rpgtocpp is defined in MOD_CPP, and prototyped below.                  
 * The mangled name of rpgtocpp is rpgtocpp__FdT1.  The name specified    
 * in the prototype's EXTPROC keyword must exactly match the mangled      
 * name of the function as exported by C++.                                
 *                                                                        
D rpgtocpp        PR                  LIKE(StdDouble)                      
D                                     EXTPROC('rpgtocpp__FdT1')
D pr_parm1                            LIKE(StdDouble) VALUE                
D pr_parm2                            LIKE(StdDouble) VALUE                
 *                                                                        
 * cpptorpg multiplies two double-precision numbers, displays the result,  
 * then returns to the caller the product it computed.                    
 * The mangled name of cpptorpg is cpptorpg__FdT1.  The name specified    
 * in the prototype's EXTPROC keyword must exactly match the mangled      
 * name of the function as imported by C++.                                
 *                                                                        
D cpptorpg        PR                  LIKE(StdDouble)                      
D                                     EXTPROC('cpptorpg__FdT1')
D pr_parm1                            LIKE(StdDouble) VALUE                
D pr_parm2                            LIKE(StdDouble) VALUE                
 *                                                                        
 * Main Program                                                            
 *                                                                        
Dglobalvar1       S                   LIKE(StdDouble)                      
 * Add the two parameters (the result is pi + pi)                          
C                   eval      globalvar1 = rpgtocpp(pi:pi)                
C                   eval      *inlr = *on                                  
 *                                                                        
 * Procedure called from C++ to multiply two parameters.                  
 *                                                                        
P cpptorpg        B                   EXPORT                              
D cpptorpg        PI                  LIKE(StdDouble)                      
D parm1                               LIKE(StdDouble) VALUE                
D parm2                               LIKE(StdDouble) VALUE                
 *                                                                        
D var1            S                   LIKE(StdDouble)                      
 *                                                                        
 * Multiply the two parameters.                                            
 *                                                                        
C                   eval      var1 = parm1 * parm2                        
 *                                                                        
 * Display result.                                                        
 *                                                                        
C     parm1         dsply                                                  
C     '*'           dsply          
C     parm2         dsply          
C     '='           dsply          
C     var1          dsply          
 *                                
 * Return result to the caller.    
 *                                
C                   return    var1
P cpptorpg        E                


C++ Source


/*                                                                            
   This module works in conjunction with RPG module MOD_RPG, which contains the
   program entry point.                                                        
*/                                                                            
                                                                               
#include <iostream.h>                                                          
using namespace std;                                                          
                                                                               
/*                                                                            
   cpptorpg multiplies two double-precision numbers, displays the result, then
   returns the result to the caller.                                          
   cpptorpg is defined in MOD_RPG, and prototyped below.  While C++ views it  
   as a function, cpptorpg is defined in ILE RPG as a subprocedure.            
   The mangled name of cpptorpg is cpptorpg__FdT1, and the RPG code is        
   designed to export the mangled name for use by C++.                        
*/                                                                            
                                                                               
double cpptorpg(double parm1, double parm2);                                  
                                                                               
/*                                                                          
   rpgtocpp adds two double-precision numbers, displays the result, then    
   calls cpptorpg with the same two parameters.  rpgtocpp then returns to the
   caller the sum it computed.                                              
   The mangled name of rpgtocpp is rpgtocpp__FdT1, and the RPG code is      
   designed to import the mangled name as exported by C++.                  
*/    
                                                                     
double rpgtocpp(double parm1, double parm2){                                
 double var1, var2;                                                          
 var1 = parm1 + parm2;                                                      
 cout << parm1 << " + " << parm2 << " = " << var1 << endl;                  
/*                                                                          
/* var2 receives the return value from cpptorpg, but the value is not used in
   this function.                                                            
*/                                                                          
 var2 = cpptorpg(parm1, parm2);                                              
 return(var1);                                                              
}                                                                            

Historical Number

25971910

Rate this page:

(0 users)Average rating

Add comments

Document information


More support for:

IBM i
Programming (Languages- compilers- tools)

Software version:

6.1, 7.1

Operating system(s):

IBM i

Reference #:

N1017083

Modified date:

2012-06-08

Translate my page

Machine Translation

Content navigation