共享内存的API
public class ShareMemory_Api
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr OpenFileMapping(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32", EntryPoint = "GetLastError")]
public static extern int GetLastError();
public const int INVALID_HANDLE_VALUE = -1;
public const int ERROR_ALREADY_EXISTS = 183;
public const int FILE_MAP_WRITE = 0x0002;
public int m_MemSize = 0;
public IntPtr m_hSharedMemoryFile = IntPtr.Zero;
public IntPtr m_pwData = IntPtr.Zero;
public const int PAGE_READWRITE = 0x04;
public string sharememoryName = "img";
public static string sharememoryNameR = "sharememoryR", sharememoryNameG = "sharememoryG", sharememoryNameB = "sharememoryB";
}
C#Pinned对象实例的类
/// <summary>
/// Object pinning class
/// </summary>
public sealed class PinnedObject : IDisposable
{
#region Field
private GCHandle _Handle; // Garbage collector handle
#endregion
#region Property
/// <summary>
/// Get the address.
/// </summary>
public IntPtr Pointer
{
// Get the leading address of the current object that is pinned.
get { return _Handle.AddrOfPinnedObject(); }
}
#endregion
#region Constructor
/// <summary>
/// Constructor
/// </summary>
/// <param name="target">Target to protect from the garbage collector</param>
public PinnedObject(object target)
{
// Pin the target to protect it from the garbage collector.
_Handle = GCHandle.Alloc(target, GCHandleType.Pinned);
}
#endregion
#region Interface
/// <summary>
/// Interface
/// </summary>
public void Dispose()
{
_Handle.Free();
_Handle = new GCHandle();
}
#endregion
}
将图像数据写到共享内存块
//将图像数据写到共享内存
//图片分三个通道
byte[] imgArryR = new byte[2448 * 2048];
byte[] imgArryG = new byte[2448 * 2048];
byte[] imgArryB = new byte[2448 * 2048];
//创建内存映射
IntPtr m_hSharedMemoryR = ShareMemory_Api.CreateFileMapping(ShareMemory_Api.INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)ShareMemory_Api.PAGE_READWRITE, 0, (uint)imgArryR.Length, ShareMemory_Api.sharememoryNameR);
IntPtr m_hSharedMemoryG = ShareMemory_Api.CreateFileMapping(ShareMemory_Api.INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)ShareMemory_Api.PAGE_READWRITE, 0, (uint)imgArryG.Length, ShareMemory_Api.sharememoryNameG);
IntPtr m_hSharedMemoryB = ShareMemory_Api.CreateFileMapping(ShareMemory_Api.INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)ShareMemory_Api.PAGE_READWRITE, 0, (uint)imgArryB.Length, ShareMemory_Api.sharememoryNameB);
//内存映射的首地址
IntPtr m_pwDataR = ShareMemory_Api.MapViewOfFile(m_hSharedMemoryR, ShareMemory_Api.FILE_MAP_WRITE, 0, 0, (uint)imgArryR.Length);
IntPtr m_pwDataG = ShareMemory_Api.MapViewOfFile(m_hSharedMemoryG, ShareMemory_Api.FILE_MAP_WRITE, 0, 0, (uint)imgArryG.Length);
IntPtr m_pwDataB = ShareMemory_Api.MapViewOfFile(m_hSharedMemoryB, ShareMemory_Api.FILE_MAP_WRITE, 0, 0, (uint)imgArryB.Length);
//获取图像三通道的首地址
HTuple R, G, B, type, Width, Height;
HOperatorSet.GetImagePointer3(g_Img, out R, out G, out B, out type, out Width, out Height);
IntPtr pSrcR = (IntPtr)R[0].L;
IntPtr pSrcG = (IntPtr)G[0].L;
IntPtr pSrcB = (IntPtr)B[0].L;
//将图像数据按地址通道复制到byte数组
System.Runtime.InteropServices.Marshal.Copy(pSrcR, imgArryR, 0, 2448 * 2048);
System.Runtime.InteropServices.Marshal.Copy(pSrcG, imgArryG, 0, 2448 * 2048);
System.Runtime.InteropServices.Marshal.Copy(pSrcB, imgArryB, 0, 2448 * 2048);
//将byte数组的数据拷贝到内存映射处
System.Runtime.InteropServices.Marshal.Copy(imgArryR, 0, m_pwDataR, 2448 * 2048);
System.Runtime.InteropServices.Marshal.Copy(imgArryG, 0, m_pwDataG, 2448 * 2048);
System.Runtime.InteropServices.Marshal.Copy(imgArryB, 0, m_pwDataB, 2448 * 2048);
将图像数据从共享内存块还原(另一个exe)
//将图像数据从共享内存块上还原
//(根据共享内存块的名字)从三个通道接收图像数据
MemoryMappedFile fileR = MemoryMappedFile.OpenExisting(ShareMemory_Api.sharememoryNameR);
MemoryMappedFile fileG = MemoryMappedFile.OpenExisting(ShareMemory_Api.sharememoryNameG);
MemoryMappedFile fileB = MemoryMappedFile.OpenExisting(ShareMemory_Api.sharememoryNameB);
//图像数据目的存放地址
byte[] byteR = new byte[2448 * 2048];
byte[] byteG = new byte[2448 * 2048];
byte[] byteB = new byte[2448 * 2048];
//开始将共享内存块的数据读取存放到字符数组
MemoryMappedViewStream streamR = fileR.CreateViewStream();
streamR.Read(byteR, 0, 2448 * 2048);
MemoryMappedViewStream streamG = fileG.CreateViewStream();
streamG.Read(byteG, 0, 2448 * 2048);
MemoryMappedViewStream streamB = fileB.CreateViewStream();
streamB.Read(byteB, 0, 2448 * 2048);
//将字符数组pineed
PinnedObject pinRData = new PinnedObject(byteR);
PinnedObject pinGData = new PinnedObject(byteG);
PinnedObject pinBData = new PinnedObject(byteB);
//根据三通道数据生成halcon类型图片变量
HObject t_img;
HOperatorSet.GenImage3(out t_img, "byte", 2448, 2048, pinRData.Pointer, pinGData.Pointer, pinBData.Pointer);