C# 共享内存怎么实现啊

supegg 2011-01-14 11:11:44
有A、B两个WPF程序,分别有一个文本框,我想在A程序文本框中输入一个字符串,然后B程序的文本框中实时重现A程序文本框的内容。
用共享内存怎么实现啊???
...全文
1202 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
bdmh 2011-01-14
  • 打赏
  • 举报
回复
用api的
CreateFileMapping()
OpenFileMapping()
LutzMark 2011-01-14
  • 打赏
  • 举报
回复
WPF进程间通讯
进程一
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
namespace WpfMain
{
/// <summary>
/// Window1.xaml 的交互逻辑
/// </summary>
public partial class Window1 : Window
{
const int WM_COPYDATA = 0x004A;
public Window1()
{
InitializeComponent ();
}


void changestyle(string strcolor)
{
}

[DllImport ("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(
int hWnd, // handle to destination window
int Msg, // message
int wParam, // first message parameter
ref COPYDATASTRUCT lParam // second message parameter
);
[DllImport ("User32.dll", EntryPoint = "FindWindow")]
private static extern int FindWindow(string lpClassName, string
lpWindowName);

private void btblack_Click(object sender, RoutedEventArgs e)
{
int WINDOW_HANDLER = FindWindow (null, "Window1");
if ( WINDOW_HANDLER != 0 )
{
byte[] sarr = System.Text.Encoding.Default.GetBytes ("Black");
int len = sarr.Length;
COPYDATASTRUCT cds;
cds.dwData = ( IntPtr )100;
cds.lpData = "Black";
cds.cbData = len + 1;
SendMessage (WINDOW_HANDLER, WM_COPYDATA, 0, ref cds);
}
}
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs (UnmanagedType.LPStr)]
public string lpData;
}
private void btblue_Click(object sender, RoutedEventArgs e)
{
int WINDOW_HANDLER = FindWindow (null, "Window1");
if ( WINDOW_HANDLER != 0 )
{
byte[] sarr = System.Text.Encoding.Default.GetBytes ("Blue");
int len = sarr.Length;
COPYDATASTRUCT cds;
cds.dwData = ( IntPtr )100;
cds.lpData = "Blue";
cds.cbData = len + 1;
SendMessage (WINDOW_HANDLER, WM_COPYDATA, 0, ref cds);
}
}

}
}

进程2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using Microsoft;
namespace WpfChildren
{
/// <summary>
/// Window1.xaml 的交互逻辑
/// </summary>
public partial class Window1 : Window
{
const int WM_COPYDATA = 0x004A;
public Window1()
{
InitializeComponent ();
}
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch ( msg )
{
case WM_COPYDATA:
Win32.CopyDataStruct st = ( Win32.CopyDataStruct )Marshal.PtrToStructure (lParam, typeof (Win32.CopyDataStruct));
string strData = Marshal.PtrToStringAnsi (st.lpData);
ChangeStyle (strData);
string[] arr = strData.Split (';');
break;
default:
break;
}
return IntPtr.Zero;
}


public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)] public string lpData;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
base.OnSourceInitialized (e);
HwndSource source = PresentationSource.FromVisual (this) as HwndSource;
source.AddHook (WndProc);
}
private void ChangeStyle(string str)
{
string stylesource = @"pack://siteoforigin:,,,/Vista" + str + ".xaml";
Application app = Application.Current;
ResourceDictionary rd = new ResourceDictionary ();
rd.Source = new Uri (stylesource, UriKind.Absolute);
app.Resources.MergedDictionaries.Add (rd);

}

}
}
mrsupersky 2011-01-14
  • 打赏
  • 举报
回复
如果是同一个程序两个窗体的话那就简单了。。。
如果是两个应用程序的话,比较复杂建议看看MSDN帮助文档,就我所知,方法也有很多,管道法不错。。。。
gaoranaa 2011-01-14
  • 打赏
  • 举报
回复
哦,没注意看你需要的是即时显示结果,这样的话建议你自己写socket比较好
gaoranaa 2011-01-14
  • 打赏
  • 举报
回复
这个,我建议你直接使用共享缓存框架吧,正好我手头有个项目需要用到缓存共享,花了N天研究内存在不同程序域之间共享的问题,也找了很多网上现成的实例,结果发现基本都有BUG,有时甚至机器卡死,后来发现了memcached,这东西你去搜一下就知道了,应该可以实现你项目的要求,单服务器多服务器之间多程序域之间的内存共享,另外还有NorthScale Memcached Server这个貌似也不错,不过查了一些技术资料发现很多人都说目前的最新版有很多BUG,打算过段时间再研究研究,现在先把手头的项目搞定,在用memcached1.6.4.1版的
萤火架构 2011-01-14
  • 打赏
  • 举报
回复
共享内存没做过,网上找到的例子:

http://www.cnblogs.com/caolisong/articles/1043152.html

还可以使用WCF
supegg 2011-01-14
  • 打赏
  • 举报
回复
我在论坛上看到一个例子,但不知道为什么我这里下不了,好心的大虫下了传给我吧。Email:supegg.rao@gmail.com
http://download.csdn.net/source/799294
supegg 2011-01-14
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 bdmh 的回复:]

用api的
CreateFileMapping()
OpenFileMapping()
[/Quote]
我找到了一个例子,有怎么用CreateFileMapping(),但是没有如何用OpenFileMapping()的,能具体介绍怎么用嘛。

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace ShareMemLib
{
public class ShareMem
{
[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();

const int ERROR_ALREADY_EXISTS = 183;

const int FILE_MAP_COPY = 0x0001;
const int FILE_MAP_WRITE = 0x0002;
const int FILE_MAP_READ = 0x0004;
const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;

const int PAGE_READONLY = 0x02;
const int PAGE_READWRITE = 0x04;
const int PAGE_WRITECOPY = 0x08;
const int PAGE_EXECUTE = 0x10;
const int PAGE_EXECUTE_READ = 0x20;
const int PAGE_EXECUTE_READWRITE = 0x40;

const int SEC_COMMIT = 0x8000000;
const int SEC_IMAGE = 0x1000000;
const int SEC_NOCACHE = 0x10000000;
const int SEC_RESERVE = 0x4000000;

const int INVALID_HANDLE_VALUE = -1;

IntPtr m_hSharedMemoryFile = IntPtr.Zero;
IntPtr m_pwData = IntPtr.Zero;
bool m_bAlreadyExist = false;
bool m_bInit = false;
long m_MemSize = 0;

public ShareMem()
{
}
~ShareMem()
{
Close();
}

/// <summary>
/// 初始化共享内存
/// </summary>
/// <param name="strName">共享内存名称</param>
/// <param name="lngSize">共享内存大小</param>
/// <returns></returns>
public int Init(string strName, long lngSize)
{
if (lngSize <= 0 || lngSize > 0x00800000) lngSize = 0x00800000;
m_MemSize = lngSize;
if (strName.Length > 0)
{
//创建内存共享体(INVALID_HANDLE_VALUE)
m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, strName);
if (m_hSharedMemoryFile == IntPtr.Zero)
{
m_bAlreadyExist = false;
m_bInit = false;
return 2; //创建共享体失败
}
else
{
if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
{
m_bAlreadyExist = true;
}
else //新创建
{
m_bAlreadyExist = false;
}
}
//---------------------------------------
//创建内存映射
m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_WRITE, 0, 0, (uint)lngSize);
if (m_pwData == IntPtr.Zero)
{
m_bInit = false;
CloseHandle(m_hSharedMemoryFile);
return 3; //创建内存映射失败
}
else
{
m_bInit = true;
if (m_bAlreadyExist == false)
{
//初始化
}
}
//----------------------------------------
}
else
{
return 1; //参数错误
}

return 0; //创建成功
}
/// <summary>
/// 关闭共享内存
/// </summary>
public void Close()
{
if (m_bInit)
{
UnmapViewOfFile(m_pwData);
CloseHandle(m_hSharedMemoryFile);
}
}

/// <summary>
/// 读数据
/// </summary>
/// <param name="bytData">数据</param>
/// <param name="lngAddr">起始地址</param>
/// <param name="lngSize">个数</param>
/// <returns></returns>
public int Read( byte[] bytData, int lngAddr, int lngSize)
{
if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
if (m_bInit)
{
Marshal.Copy(m_pwData, bytData, lngAddr, lngSize);
}
else
{
return 1; //共享内存未初始化
}
return 0; //读成功
}

/// <summary>
/// 写数据
/// </summary>
/// <param name="bytData">数据</param>
/// <param name="lngAddr">起始地址</param>
/// <param name="lngSize">个数</param>
/// <returns></returns>
public int Write(byte[] bytData, int lngAddr, int lngSize)
{
if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
if (m_bInit)
{
Marshal.Copy(bytData, lngAddr, m_pwData, lngSize);
}
else
{
return 1; //共享内存未初始化
}
return 0; //写成功
}
}
}
xonln 2011-01-14
  • 打赏
  • 举报
回复
C#操作内存相当的弱,还是用C++吧,真的

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧