"Go" Unity interprocess communication Unity Hook Wm_copydata

Source: Internet
Author: User

Original stickers:

Unity3d process communication using wm_copydare and hooks

Hello, the recent use of unity to do the process of communication, should be and C + + PC-side implementation of communication, only began to confused, and then realized that it is very complicated ... First of all, I would appreciate the help of Baidu, Google and the game circle of the big players.

There are many ways to communicate in a process, but wm_copydate is definitely much better than other memory shares. Most of unity is in C # language, C # ability Forms This DLL also provides the reception of Windows messages but not in unity to use System.Windows.Forms very well, so in the following my Code I use Unity to send process messages is User32.dll in the SendMessage, for the receiving is used Hook (hook). The following code is the communication of the EXE packaged by unity. will not communicate with C + +, the principle is the same.

The entire process to import user32.dll, so in need of using System.Runtime.InteropServices; what else to add, and there is the sending of JSON data and many details of the C # fetch address read address, I also share the fun , I will help you later.

Send side (using SendMessage), Test1.cs mounted in unity scene

Using System;
Using Unityengine;
Using System.Collections;
Using System.Runtime.InteropServices;
Using System.Text;


public class Test15:monobehaviour
{
#region
Public IntPtr m_hwnd;

<summary>
Send Windows messages easy to use with the SendMessage function in User32.dll
</summary>
public struct COPYDATASTRUCT
{
Public IntPtr dwdata;
public int cbdata;
Public INTPTR lpdata;
}

The SendMessage in User32.dll
[DllImport ("User32.dll")]
public static extern IntPtr SendMessage (IntPtr hWnd, uint Msg, int wParam, ref copydatastruct LParam);
Get form handle in User32.dll
[DllImport ("User32.dll")]
public static extern IntPtr FindWindow (string strclassname, string strwindowname);

Macro definition

Private Const USHORT Ipc_ver = 1;
Private Const int idt_asynchronism = 0x0201;
Private Const UINT WM_COPYDATA = 0x004a;
Private Const USHORT Ipc_cmd_gf_socket = 1;
Private Const USHORT Ipc_sub_gf_socket_send = 1;
Private Const int ipc_sub_gf_client_ready = 1;
Private Const int Ipc_cmd_gf_control = 2;
Private Const int ipc_buffer = 10240;//Max buffer length

Find a form

Private INTPTR Hwndpalaz;

Data header with
Public unsafe struct Ipc_head
{
public ushort Wversion;
public ushort Wpacketsize;
public ushort Wmaincmdid;
public ushort Wsubcmdid;




}
Public unsafe struct Ipc_buffer
{
Public Ipc_head Head; Ipc_head structure
Public fixed byte cbbuffer[ipc_buffer]; Pointer holds JSON data using byte[] to receive storage
}

#endregion

<summary>
Send JSON to Pointer to SendData () method
</summary>
private void Sendjson () {
IntPtr Hwndpalaz = FindWindow (null, "The name of the form you are looking for");//is the title of the form
Debug.Log (Hwndpalaz);
if (Hwndpalaz! = null)
{
Get the handle of the game itself
M_hwnd = FindWindow ("Unitywndclass", null);




Send the user to prepare the message (this is a JSON plugin I will not provide your own JSON new instance of the example here do not change the error)
Jsonobject Jsstart = new Jsonobject ();
Jsstart.addfield ("66", "It's Me");
Jsstart.addfield ("Sya", "Learning game in order to install Force Group");
Jsstart.addfield ("Doing", "This Is your Time");


String urstr = Jsstart.tostring ();
byte[] bytes = Encoding.UTF8.GetBytes (URSTR);
IntPtr pData = marshal.allochglobal (2 * bytes. Length);
Marshal.Copy (bytes, 0, PData, bytes. Length);
SendData (M_hwnd, Ipc_cmd_gf_socket, Ipc_sub_gf_socket_send, PData, (ushort) bytes. Length);


}

}

<summary>
SendMessage Send
</summary>
<param name= "Hwndserver" > Hands </param>
<param name= "Wmaincmdid" > Main command </param>
<param name= "Wsubcmdid" > Times Command </param>
<param name= "PData" >json conversion pointer </param>
<param name= "Wdatasize" > Data size </param>
<returns></returns>
Public unsafe bool SendData (IntPtr hwndserver, ushort Wmaincmdid, ushort Wsubcmdid, IntPtr pData, ushort wdatasize)
{
Assigning values to Ipcbuffer structures
Ipc_buffer Ipcbuffer;
IPCBuffer.Head.wVersion = Ipc_ver;
IPCBuffer.Head.wSubCmdID = Wsubcmdid;
IPCBuffer.Head.wMainCmdID = Wmaincmdid;
IPCBuffer.Head.wPacketSize = (ushort) marshal.sizeof (typeof (Ipc_head));


Memory operations
if (pData! = null)
{
Efficacy length
if (Wdatasize > 1024x768) return false;
Copy data
IPCBuffer.Head.wPacketSize + = Wdatasize;


byte[] bytes = new Byte[ipc_buffer];
Marshal.Copy (pData, Bytes, 0, wdatasize);


for (int i = 0; i < Ipc_buffer; i++)
{
Ipcbuffer.cbbuffer[i] = bytes[i];
}
}


Send data
Copydatastruct copydatastruct;
ipc_buffer* Ppcbuffer = &IPCBuffer;
Copydatastruct.lpdata = (IntPtr) ppcbuffer;
Copydatastruct.dwdata = (IntPtr) idt_asynchronism;
Copydatastruct.cbdata = IPCBuffer.Head.wPacketSize;
SendMessage (Hwndserver, 0x004a, (int) m_hwnd, ref copydatastruct);


return true;
}
void Update ()
{
Sendjson ();//Always send a convenient test
}
}

Receive end Test2.cs random scene Save the script to mount the scene of the object above, and then use Unity to pack the PC-side EXE receive the use of Windows Hook Hook (here I do not do detailed comments, I feel the magic of the hook, do not understand can give me a message)

Using Unityengine;
Using System;
Using System.Diagnostics;
Using System.Runtime.InteropServices;
Using Debug = Unityengine.debug;

public class Test2:monobehaviour
{

Structure of the hook receiving message

public struct CWPSTRUCT
{
public int lparam;
public int wparam;
public UINT Message;
Public INTPTR hwnd;
}

Build Hooks
[DllImport ("user32.dll", CharSet = CharSet.Auto, callingconvention = Callingconvention.stdcall)]
private static extern int SetWindowsHookEx (int idhook, HookProc lpfn, IntPtr hinstance, uint dwthreadid);


Remove hooks
[DllImport ("user32.dll", CharSet = CharSet.Auto, callingconvention = Callingconvention.stdcall)]
private static extern bool UnhookWindowsHookEx (int idhook);


Pass the message to the next listener
[DllImport ("user32.dll", CharSet = CharSet.Auto, callingconvention = Callingconvention.stdcall)]
private static extern int CallNextHookEx (int idhook, int nCode, int wParam, int lParam);

Callback delegate
Private delegate int HookProc (int nCode, int wParam, int lParam);
Hook
int idhook = 0;
Is the hook installed?
BOOL Ishook = false;

GCHandle GC;
Private Const int WH_CALLWNDPROC = 4; Hook type Global Hooks

Define structure and send structure correspondence

Public unsafe struct Ipc_head
{
public int wversion;
public int wpacketsize;
public int wmaincmdid;
public int wsubcmdid;
}
Private Const int ipc_buffer = 10240;//Max buffer length
Public unsafe struct Ipc_buffer
{
Public Ipc_head Head;
Public fixed byte cbbuffer[ipc_buffer]; Where JSON data is stored
}

public struct COPYDATASTRUCT
{
public int dwdata;
public int cbdata;
Public INTPTR lpdata;
}

void Start ()
{

Mounting hooks
Hookload ();
}


void OnDestroy ()
{

Close Hooks
Hookclosing ();
}

private void Hookload ()
{
Debug.Log ("Start Running");
Mounting hooks
{
Hook delegate
HookProc LPFN = new HookProc (Hook);
The main module of the associated process
IntPtr hinstance = intptr.zero;//GetModuleHandle (process.getcurrentprocess (). Mainmodule.modulename);
Idhook = SetWindowsHookEx (Wh_callwndproc, LPFN, HINSTANCE, (UINT) appdomain.getcurrentthreadid ());
if (Idhook > 0)
{
Debug.Log ("hook [" + Idhook + "] installation succeeded");
Ishook = true;
Keep Active to prevent callback process from being garbage collected
GC = GCHandle.Alloc (LPFN);
}
Else
{
Debug.Log ("Hook installation Failed");
Ishook = false;
UnhookWindowsHookEx (Idhook);
}
}
}


Uninstalling Hooks
private void Hookclosing ()
{
if (Ishook)
{
UnhookWindowsHookEx (Idhook);
}
}


private bool _bcallnext;
public bool Callnextproc
{
get {return _bcallnext;}
set {_bcallnext = value;}
}





Hook callback


private unsafe int Hook (int nCode, int wParam, int lParam)
{


Try
{
INTPTR p = new IntPtr (LParam);
Cwpstruct m = (cwpstruct) marshal.ptrtostructure (P, typeof (Cwpstruct));

if (M.message = = 74)
{
Copydatastruct entries = (copydatastruct) marshal.ptrtostructure ((INTPTR) m.LParam, typeof (Copydatastruct));
Ipc_buffer entries1 = (ipc_buffer) marshal.ptrtostructure ((INTPTR) Entries.lpdata, typeof (Ipc_buffer));

IntPtr intp = new IntPtr (entries1.cbbuffer);
String str = new String ((sbyte*) INTP);
Debug.Log ("JSON data:" + str);
}
if (Callnextproc)
{
Return CallNextHookEx (Idhook, NCode, WParam, LParam);
}
Else
{
return 1;
Return CallNextHookEx (Idhook, NCode, WParam, LParam);
}
}
catch (Exception ex)
{
Debug.Log (ex. Message);
return 0;
}

}
}

OK, all the code is finally over, pack the Test2.cs scene, put the Test1.cs code in unity and run the line. Finally look at the Test2.cs EXE in the code took me a long time, very valuable I so share to everyone, I hope you have good things also don't stingy ah. Hey, finally have not understand can add my Q group 479853988 asked me Oh. Many great gods can also ask. Reprint focus on the original OH.

"Go" Unity interprocess communication Unity Hook Wm_copydata

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.