The MASM Forum

64 bit assembler => 64 bit assembler. Conceptual Issues => Topic started by: jj2007 on October 28, 2016, 11:19:40 AM

Title: Sharing data between 32- and 64-bit applications
Post by: jj2007 on October 28, 2016, 11:19:40 AM
Here is a simple server-client pair, where server is a 32-bit console application:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi="{\rtf1\ansi This is \b bold \b0 text}"      ; the client understands RTF, too ;)
  .Repeat
      Let esi=Input$("Type the text to send, or Esc & Return to exit: ", esi)
      SendData "Hello World64", esi
  .Until !Len(esi)
EndOfCode


The server uses SendData (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1082) (about 160k max). At the receiving end, a simple handler sets the text to a RichEdit control:
  Case_ WM_COPYDATA
jinvoke SetWindowText, hEdit, wmcd$()


The client can be built as 32- or 64-bit application, using ML/ML64/HJWasm/AsmC:include \Masm32\MasmBasic\Res\JBasic.inc ; hit F6 to build this program
.data ; OPT_64 1 ; 0=32-bit, 1=64-bit assembly
wcx WNDCLASSEX <WNDCLASSEX, CS_HREDRAW or CS_VREDRAW or CS_OWNDC, WndProc, 0, 0, 1, 2, 3, COLOR_BTNFACE+1, 0, txClass, SIZE_P>
txClass db "JBasicGUI", 0 ; OPT_Assembler ML ; try HJWasm or AsmC, too
hEdit SIZE_P ? ; the handle to the edit control is a pointer, 32 or 64 bits wide
Init
WinMain proc
LOCAL msg:MSG
  wc equ [rbx.WNDCLASSEX] ; we use an equate for better readability
  lea rbx, wcx
  mov wc.hInstance, rv(GetModuleHandle, 0)
  mov wc.hIcon, rv(LoadIcon, rax, IDI_APPLICATION) ; click on the first Rsrc bookmark to change the icon
  mov wc.hIconSm, rax ; the rv macro returns results in rax
  mov wc.hCursor, rv(LoadCursor, NULL, IDC_ARROW) ; get a cursor
  jinvoke RegisterClassEx, rbx ; the window class needs to be registered
  wsStyle=WS_OVERLAPPED or WS_VISIBLE or WS_CLIPCHILDREN or WS_SYSMENU
  jinvoke CreateWindowEx, WS_EX_TOPMOST, wc.lpszClassName, Chr$("Hello World64"), wsStyle, 300+320*@64, 127, 700, 600, NULL, rv(LoadMenu, wc.hInstance, 100), wc.hInstance, NULL
  msgLoop: jinvoke TranslateMessage, addr msg ; translates virtual-key messages into character messages
jinvoke DispatchMessage, addr msg ; dispatches a message to a window procedure
jinvoke GetMessage, addr msg, 0, 0, 0 ; retrieve a message from the queue, and return a BOOL
mcs inc eax : shr eax, 1 : jne msgLoop ; quit if GetMessage returned 0 (exit OK) or -1 (error)
  jinvoke ExitProcess, msg.wParam
WinMain endp
wmcd$ macro
  mov rax, lParam
  EXITM <[rax.COPYDATASTRUCT.lpData]>
ENDM
WndProc proc <cb cs> uses rsi rdi rbx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
  Switch_ uMsg
  Case_ WM_COPYDATA
jinvoke SetWindowText, hEdit, wmcd$()
  Case_ WM_CREATE
reStyle=WS_VISIBLE or WS_CHILD or ES_MULTILINE or WS_VSCROLL or WS_HSCROLL or ES_AUTOHSCROLL or ES_AUTOVSCROLL or ES_NOHIDESEL
jinvoke LoadLibrary, Chr$("RichEd20") ; we want to add a RichEdit control
mov hEdit, rv(CreateWindowEx, WS_EX_CLIENTEDGE, Chr$("RichEdit20A"), NULL, reStyle, 3, 3, 700-12, 600-30, hWnd, 111, wcx.hInstance, NULL)
jinvoke SendMessage, hEdit, EM_SETTARGETDEVICE, 0, 0 ; word wrap on
jinvoke SendMessage, hEdit, EM_EXLIMITTEXT, 0, -1 ; no limit
jinvoke SendMessage, hEdit, WM_SETFONT, rv(GetStockObject, ANSI_FIXED_FONT), 0
jinvoke SetWindowText, hEdit, Str$(Chr$("This program was built with", 13, 10, @AsmUsed$(1), " in %i-bit mode", 13, 10), jBits)
  Case_ WM_DESTROY
jinvoke PostQuitMessage, NULL
  Endsw_
  mcs jinvoke DefWindowProc, hWnd, uMsg, wParam, lParam : ret
WndProc endp
EndOfCode ; OPT_Icon Eye
Title: Re: Sharing data between 32- and 64-bit applications
Post by: mabdelouahab on October 28, 2016, 06:02:14 PM
Good idea jj2007  :t
For me I use COM LocalServers
Title: Re: Sharing data between 32- and 64-bit applications
Post by: MichaelW on October 29, 2016, 04:20:42 AM
The 160K max was determined by test, or is it documented somewhere?
Title: Re: Sharing data between 32- and 64-bit applications
Post by: jj2007 on October 29, 2016, 07:26:06 AM
160k is the limit of the internal MasmBasic circulary buffer. SendData (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1082) was not meant for big strings; but you are right that it should be documented :bgrin:
Title: Re: Sharing data between 32- and 64-bit applications
Post by: hutch-- on October 29, 2016, 08:23:50 AM
Has anyone tried memory mapped files yet. I know you can use TCP/IP like some of the databases do, the other comment is whether messaging works across the 32/64 bit boundary, IE: SendMessage HWND_BROADCAST with private messages for example. I will get around to testing this stuff but I have too much to do at the moment.
Title: Re: Sharing data between 32- and 64-bit applications
Post by: mabdelouahab on October 29, 2016, 09:28:43 AM
Quote from: hutch-- on October 29, 2016, 08:23:50 AM
Has anyone tried memory mapped files yet. I know you can use TCP/IP like some of the databases do, the other comment is whether messaging works across the 32/64 bit boundary, IE: SendMessage HWND_BROADCAST with private messages for example. I will get around to testing this stuff but I have too much to do at the moment.
Easy
Run the 32bit app, then run the 64bit app, press Ok (MessageBox), and see what happens to the 32bit app
32bit:

include masm32rt.inc
.data
lpFileMapping dd 0
lpBaseAddr dd 0
.code
Start:
invoke CreateFileMapping,INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, NULL, 1024, chr$("Sh3264.333")
.if eax
mov lpFileMapping,eax
invoke MapViewOfFile,lpFileMapping, FILE_MAP_ALL_ACCESS , NULL, NULL, NULL
.if eax
mov lpBaseAddr,eax
printf("\n Value = 144 \n Wait while Value = 64.\n")
mov edi,lpBaseAddr
mov dword ptr [edi],144
@@:
mov eax,dword ptr [edi]
cmp eax,64
jne @B

printf("\n Now Value = 64 \n")
invoke UnmapViewOfFile,lpBaseAddr
.endif
invoke CloseHandle,lpFileMapping
.endif
inkey
exit
End Start

64bit:
include X64.inc
include win64.inc
Include_lib kernel32
Include_lib user32
Include_lib msvcrt
  .data
lpFileMapping dq 0
lpBaseAddr dq 0
  .code

main proc
.invoke OpenFileMapping,FILE_MAP_ALL_ACCESS, FALSE, "Sh3264.333"
.if RAX
mov lpFileMapping,RAX
.invoke MapViewOfFile,lpFileMapping, FILE_MAP_ALL_ACCESS , NULL, NULL, NULL
.if RAX
mov lpBaseAddr,RAX
mov RDI,lpBaseAddr
.invoke vc_printf ,"Value =%d",dword ptr [RDI]
.invoke MessageBox,0,"Any Key To set Value = 64",0,0
mov RDI,lpBaseAddr
mov dword ptr [RDI],64
.invoke UnmapViewOfFile,lpBaseAddr
.endif
.invoke CloseHandle,lpFileMapping
.endif
.invoke ExitProcess,0
main endp
end 

Title: Re: Sharing data between 32- and 64-bit applications
Post by: jj2007 on October 29, 2016, 10:07:01 AM
Quote from: hutch-- on October 29, 2016, 08:23:50 AMthe other comment is whether messaging works across the 32/64 bit boundary

The SendData (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1082) macro uses the WM_COPYDATA message.