News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Sharing data between 32- and 64-bit applications

Started by jj2007, October 28, 2016, 11:19:40 AM

Previous topic - Next topic

jj2007

Here is a simple server-client pair, where server is a 32-bit console application:

include \masm32\MasmBasic\MasmBasic.inc      ; download
  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 (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

mabdelouahab

Good idea jj2007  :t
For me I use COM LocalServers

MichaelW

The 160K max was determined by test, or is it documented somewhere?
Well Microsoft, here's another nice mess you've gotten us into.

jj2007

160k is the limit of the internal MasmBasic circulary buffer. SendData was not meant for big strings; but you are right that it should be documented :bgrin:

hutch--

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.

mabdelouahab

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 


jj2007

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 macro uses the WM_COPYDATA message.