/// <summary> /// Send a message to the engine /// </summary> /// <param name="message"></param> public void sendMessage(TMsgHeader message) { TNativeMsgHeader msgPtr = new TNativeMsgHeader(); uint nBytes = message.nDataBytes; try { msgPtr.version = message.version; msgPtr.msgType = message.msgType; msgPtr.from = message.from; msgPtr.to = message.to; msgPtr.msgID = message.msgID; msgPtr.toAck = message.toAck; msgPtr.nDataBytes = nBytes; if (nBytes == 0) { msgPtr.dataPtr = IntPtr.Zero; } else { msgPtr.dataPtr = Marshal.AllocHGlobal((int)nBytes); Marshal.Copy(message.dataPtr, 0, msgPtr.dataPtr, (int)nBytes); } _callengine(ref componentID, ref msgPtr); } finally { if (nBytes > 0) { Marshal.FreeHGlobal(msgPtr.dataPtr); } } }
//============================================================================== /// <summary> /// Send a message up to the owning system so it can be routed throughout /// the simulation. Overridden to allow the message data to be converted /// to a native pointer. /// </summary> /// <param name="msg">Message that will be sent to the engine.</param> //============================================================================== protected override void sendMessageToEngine(TMsgHeader msg) { // Copy from TMsgHeader to TNativeMsgHeader. // The difference is in the nature of the data pointer. try { TNativeMsgHeader msgPtr = new TNativeMsgHeader(); uint nBytes = msg.nDataBytes; try { msgPtr.version = msg.version; msgPtr.msgType = msg.msgType; msgPtr.from = msg.from; msgPtr.to = msg.to; msgPtr.msgID = msg.msgID; msgPtr.toAck = msg.toAck; msgPtr.nDataBytes = nBytes; if (nBytes == 0) { msgPtr.dataPtr = IntPtr.Zero; } else { /* * if (nBytes > memAllocSize) * { * * if (memAllocSize > 0) * Marshal.FreeHGlobal(nativeMem); * nativeMem = Marshal.AllocHGlobal((int)nBytes); * memAllocSize = nBytes; * } * msgPtr.dataPtr = nativeMem; */ msgPtr.dataPtr = Marshal.AllocHGlobal((int)nBytes); Marshal.Copy(msg.dataPtr, 0, msgPtr.dataPtr, (int)nBytes); } IntPtr dummy = (IntPtr)0; msgNativeDestFunction(ref dummy, ref msgPtr); //will take a copy } finally { if (nBytes > 0) { Marshal.FreeHGlobal(msgPtr.dataPtr); } } } catch (SEHException) { // This is the most likely exception to be caught here, but normally it will } // be handled elsewhere on the native side, and "External component has thrown an exception" is not a very helpful message catch (Exception e) { StringBuilder exmsg = new StringBuilder("sendMessageToEngine() failed "); exmsg.Append(e.Message); Console.WriteLine(exmsg); } }
//private uint memAllocSize = 0; //private IntPtr nativeMem; //============================================================================== /// <summary> /// Send a message up to the owning system so it can be routed throughout /// the simulation. Overridden to allow the message data to be converted /// to a native pointer. This enables calling from embedded Microsoft Frameworks or Mono. /// The message itself then needs to be converted from a TNativeMsgHeader to a TMsgHeader, /// which includes taking a copy of the data referenced by the data pointer /// </summary> /// <param name="inVal">Message that will be sent to the engine. /// The value passed in, although described as a "ulong", is actually /// a pointer to a native TMsgHeader /// </param> //============================================================================== public void handleMessage(ulong inVal) { // We need to copy the "native" message point into a managed object. TNativeMsgHeader src = (TNativeMsgHeader)Marshal.PtrToStructure((IntPtr)inVal, typeof(TNativeMsgHeader)); TMsgHeader msgPtr = TMessageInterpreter.NativeMsgToManagedMsg(ref src); handleMessage(msgPtr); //calls the base class function }
//============================================================================== /// <summary> /// Send a message up to the owning system so it can be routed throughout /// the simulation. Overridden to allow the message data to be converted /// to a native pointer. /// </summary> /// <param name="msg">Message that will be sent to the engine.</param> //============================================================================== protected override void sendMessageToEngine(TMsgHeader msg) { // Copy from TMsgHeader to TNativeMsgHeader. // The difference is in the nature of the data pointer. try { TNativeMsgHeader msgPtr = new TNativeMsgHeader(); uint nBytes = msg.nDataBytes; try { msgPtr.version = msg.version; msgPtr.msgType = msg.msgType; msgPtr.from = msg.from; msgPtr.to = msg.to; msgPtr.msgID = msg.msgID; msgPtr.toAck = msg.toAck; msgPtr.nDataBytes = nBytes; if (nBytes == 0) { msgPtr.dataPtr = IntPtr.Zero; } else { /* * if (nBytes > memAllocSize) * { * * if (memAllocSize > 0) * Marshal.FreeHGlobal(nativeMem); * nativeMem = Marshal.AllocHGlobal((int)nBytes); * memAllocSize = nBytes; * } * msgPtr.dataPtr = nativeMem; */ msgPtr.dataPtr = Marshal.AllocHGlobal((int)nBytes); Marshal.Copy(msg.dataPtr, 0, msgPtr.dataPtr, (int)nBytes); } uint dummy = 0; msgNativeDestFunction(ref dummy, ref msgPtr); //will take a copy } finally { if (nBytes > 0) { Marshal.FreeHGlobal(msgPtr.dataPtr); } } } catch (Exception e) { StringBuilder exmsg = new StringBuilder("sendMessageToEngine() failed "); exmsg.Append(e.Message); Console.WriteLine(exmsg); } }