Assembly language > Assembly discussions
Calling a C++ function from Poasm
Vortex:
Here is a Poasm example calling a MS VC module :
--- Code: ---#define _NO_CRT_STDIO_INLINE
#include <stdio.h>
class formula {
public:
int calc(int, int, int, int, int);
void GetResult(int);
};
int formula::calc(int a, int b, int c, int d, int e)
{
return a * b * c * d * e;
}
void formula::GetResult(int t)
{
printf("The result is %u\n",t);
}
--- End code ---
rcx points the "this" pointer, it must be skipped :
--- Code: ---EXTERN ?calc@formula@@QEAAHHHHHH@Z:PROC
calc TEXTEQU <?calc@formula@@QEAAHHHHHH@Z>
EXTERN ?GetResult@formula@@QEAAXH@Z:PROC
GetResult TEXTEQU <?GetResult@formula@@QEAAXH@Z>
ExitProcess PROTO :QWORD
.code
start PROC PARMAREA=6*QWORD
; rcx -> this pointer
mov rdx,2
mov r8,4
mov r9,6
mov QWORD PTR [rsp+32],8
mov QWORD PTR [rsp+40],10
call calc
; rcx -> this pointer
mov rdx,rax
call GetResult
invoke ExitProcess,0
start ENDP
END start
--- End code ---
Vortex:
Same example with function prototypes :
--- Code: ---?calc@formula@@QEAAHHHHHH@Z PROTO :QWORD,:QWORD,:QWORD,:QWORD,:QWORD,:QWORD
calc TEXTEQU <?calc@formula@@QEAAHHHHHH@Z>
?GetResult@formula@@QEAAXH@Z PROTO :QWORD,:QWORD
GetResult TEXTEQU <?GetResult@formula@@QEAAXH@Z>
ExitProcess PROTO :QWORD
.code
start PROC PARMAREA=6*QWORD
; rcx -> this pointer
invoke calc,rcx,2,4,6,8,10
; rcx -> this pointer
invoke GetResult,rcx,rax
invoke ExitProcess,0
start ENDP
END start
--- End code ---
TimoVJL:
Why not with C ;)
--- Code: ---void __stdcall ExitProcess( unsigned int uExitCode);
int __cdecl printf(const char * format, ...);
#pragma comment(lib, "msvcrt.lib")
// void formula::GetResult(int t)
// void ?GetResult@formula@@QEAAXH@Z(long long, long long)
#pragma comment(linker, "-alternatename:formula_GetResult=?GetResult@formula@@QEAAXH@Z")
void formula_GetResult(void* this, int t);
// int formula::calc(int a, int b, int c, int d, int e)
// int ?calc@formula@@QEAAHHHHHH@Z(int a, int b, int c, int d, int e)
int formula_calc(void* this, int a, int b, int c, int d, int e);
#pragma comment(linker, "-alternatename:formula_calc=?calc@formula@@QEAAHHHHHH@Z")
void __cdecl mainCRTStartup(void)
{
int x = formula_calc(0,2,4,6,8,10);
formula_GetResult(0,x);
ExitProcess(0);
}
--- End code ---
Vortex:
Hi Timo,
Great sample, many thanks. Something new to learn for me, it's the /ALTERNATENAME:symbol=symbol option of polink.
The linker option ALTERNATENAME does the job, disassembling the object module produced by Pelles C :
--- Code: ---public mainCRTStartup
extern ExitProcess: near
extern formula_GetResult: near
extern formula_calc: near
_text SEGMENT PARA 'CODE'
mainCRTStartup PROC
sub rsp, 56
mov dword ptr [rsp+28H], 10
mov dword ptr [rsp+20H], 8
xor ecx, ecx
mov edx, 2
mov r8d, 4
mov r9d, 6
call formula_calc
xor ecx, ecx
mov edx, eax
call formula_GetResult
xor ecx, ecx
call ExitProcess
add rsp, 56
ret
mainCRTStartup ENDP
--- End code ---
Vortex:
Hi Timo,
I updated my code to remove the name mangling :
--- Code: ---calc PROTO :QWORD,:QWORD,:QWORD,:QWORD,:QWORD,:QWORD
GetResult PROTO :QWORD,:QWORD
ExitProcess PROTO :QWORD
.code
start PROC PARMAREA=6*QWORD
; rcx -> this pointer
invoke calc,rcx,2,4,6,8,10
; rcx -> this pointer
invoke GetResult,rcx,rax
invoke ExitProcess,0
start ENDP
END start
--- End code ---
Linking the object modules :
--- Code: ---\PellesC\bin\polink /SUBSYSTEM:CONSOLE /LARGEADDRESSAWARE /LIBPATH:\PellesC\lib\Win64 /ALTERNATENAME:GetResult=?GetResult@formula@@QEAAXH@Z /ALTERNATENAME:calc=?calc@formula@@QEAAHHHHHH@Z CallCppFunc.obj Class.obj kernel32.lib msvcrt.lib
--- End code ---
Navigation
[0] Message Index
[#] Next page
Go to full version