Страница: 1 |
Страница: 1 |
Вопрос: Ахтунг ! Shared Memory ! На Конец то !
Добавлено: 20.11.05 21:38
Автор вопроса: student-uni
Один парняга по имени Саша Маранди написал интерпроцесс комюникейшн через шаред мемори.
Ну что сказать:
1. Автору - спасибо.
2. ВБ.НЕТ - это круто.
3. Всё гениальное просто.
4. Век живи век учись, а в компиляторе ошибки.
Imports System.Runtime.InteropServices
Public Class frmMain
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
'myShareData.Close()
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents btnPut As System.Windows.Forms.Button
Friend WithEvents btnPeek As System.Windows.Forms.Button
Friend WithEvents txtData As System.Windows.Forms.TextBox
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.btnPut = New System.Windows.Forms.Button
Me.btnPeek = New System.Windows.Forms.Button
Me.txtData = New System.Windows.Forms.TextBox
Me.SuspendLayout()
'
'btnPut
'
Me.btnPut.Location = New System.Drawing.Point(32, 48)
Me.btnPut.Name = "btnPut"
Me.btnPut.TabIndex = 1
Me.btnPut.Text = "Put Data"
'
'btnPeek
'
Me.btnPeek.Location = New System.Drawing.Point(112, 48)
Me.btnPeek.Name = "btnPeek"
Me.btnPeek.TabIndex = 2
Me.btnPeek.Text = "Peek Data"
'
'txtData
'
Me.txtData.Location = New System.Drawing.Point(16, 16)
Me.txtData.Name = "txtData"
Me.txtData.Size = New System.Drawing.Size(184, 20)
Me.txtData.TabIndex = 0
Me.txtData.Text = "Shasa Marandi"
'
'frmMain
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(216, 86)
Me.Controls.Add(Me.txtData)
Me.Controls.Add(Me.btnPeek)
Me.Controls.Add(Me.btnPut)
Me.Name = "frmMain"
Me.Text = "Shared Memory"
Me.ResumeLayout(False)
End Sub
#End Region
Private myShareData As New SharedMemory 'Shared Memory Class
Private Sub btnPut_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPut.Click
'Put Message to memory
myShareData.Put(Me.txtData.Text)
End Sub
Private Sub btnPeek_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPeek.Click
'Check data exist and show message
If myShareData.DataExists Then
Me.txtData.Text = myShareData.Peek()
Else
Me.txtData.Text = "Empty"
End If
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Create or Open space in memory
myShareData.Open("S0") 'Space 0
End Sub
End Class
Imports System.Runtime.InteropServices
Public Class SharedMemory
'APIs
Private Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Integer, ByVal lpFileMappigAttributes As Integer, ByVal flProtect As Integer, ByVal dwMaximumSizeHigh As Integer, ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As Integer
Private Declare Function MapViewOfFile Lib "kernel32" Alias "MapViewOfFile" (ByVal hFileMappingObject As Integer, ByVal dwDesiredAccess As Integer, ByVal dwFileOffsetHigh As Integer, ByVal dwFileOffsetLow As Integer, ByVal dwNumberOfBytesToMap As Integer) As IntPtr
Private Declare Function UnmapViewOfFile Lib "kernel32" Alias "UnmapViewOfFile" (ByVal lpBaseAddress As IntPtr) As Integer
Private Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Integer) As Integer
'Constants
Private Const FILE_MAP_ALL_ACCESS As Integer = &HF001F
Private Const PAGE_READWRITE As Integer = &H4
Private Const INVALID_HANDLE_VALUE As Integer = -1
'Variables
Private FileHandle As Integer
Private SharePoint As IntPtr
#Region " Open and Close (Memory) Procedures "
Public Function Open(ByVal MemoryName As String) As Boolean
'Get a handle to an area of memory and name it the name passed in MemoryName.
'Any application that maps an area of memory with that name gets the same
'address, so data can be shared.
'Note: the INVALID_HANDLE_VALUE, which tells windows not to use a file but
'just memory.
FileHandle = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 128, MemoryName)
'Get a pointer to the area of memory we mapped.
If Not FileHandle = 0 Then
SharePoint = MapViewOfFile(FileHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0)
Else
Return False
End If
End Function
Public Sub Close()
'Close the memory handle.
UnmapViewOfFile(SharePoint)
CloseHandle(FileHandle)
End Sub
Protected Overrides Sub Finalize()
'Close the memory handle
Call Close()
'Finalize Base Class
MyBase.Finalize()
End Sub
#End Region
Public Function Peek() As String
'Copy the data length to a variable.
Dim myDataLength As Integer = Marshal.ReadInt32(SharePoint)
'Create an array to hold the data in memory.
Dim myBuffer(myDataLength - 1) As Byte
'Copy the data in memory to the array.
Marshal.Copy(New IntPtr(SharePoint.ToInt32 + 4), myBuffer, 0, myDataLength)
'Return Output (Unicode)
Return System.Text.Encoding.UTF8.GetString(myBuffer)
End Function
Public Sub Put(ByVal Data As String)
'Create an array with one element for each character. (Unicode)
Dim myBuffer As Byte() = System.Text.Encoding.UTF8.GetBytes(Data)
'Copy the length of the string into the first four bytes of the memory location
Marshal.WriteInt32(SharePoint, Data.Length)
'Copy the string data to memory right after the length.
Marshal.Copy(myBuffer, 0, New IntPtr(SharePoint.ToInt32 + 4), myBuffer.Length)
End Sub
Public Sub ResetMemory()
'Reset Data Lenght (Set Data Length to 0 - Empty)
Marshal.WriteInt32(SharePoint, 0I)
End Sub
Public ReadOnly Property DataExists() As Boolean
Get
'Copy the data length to a variable.
Dim myDataLength As Integer = Marshal.ReadInt32(SharePoint)
If Not myDataLength = 0 Then Return True
End Get
End Property
End Class
Ответы
Всего ответов: 11
Номер ответа: 1
Автор ответа:
⊗WaX⊗
Вопросов: 26
Ответов: 325
Web-сайт:
Профиль | | #1
Добавлено: 20.11.05 23:37
Thanks a lot
Прям вот сейчас и пригодилось
Удачи
Номер ответа: 2
Автор ответа:
student-uni
Вопросов: 122
Ответов: 257
Профиль | | #2
Добавлено: 20.11.05 23:56
Это очень нехилая штуковина.
Но есть одно но.
Если надо иметь доступ к определённым
данным процесса, эта мама не очень.
Смотрите:
Private myShareData As New SharedMemory
Все процессы пишут в одну myShareData.
А можно ли как то сделать,
чтобы новому объекту давалось имя не
myShareData
а
номерSID ? /естественно SID априори известен/
Т.о. это что-то типа
Private mySID As New SharedMemory
Где SID - переменная куда впишем номер процесса в RAMe.
НУ в общем можно ли, чтоб имя нового
объекта было как бы переменная ? А ?
Представляете насколько круче можно
использовать ?
Ты находишь СИД процесса
и по
mySID.Peek()
вынимаешь нужную тебе инфу конкретного процесса.
Спасибо за идеи.
Номер ответа: 3
Автор ответа:
Павел
Администратор
ICQ: 326066673
Вопросов: 368
Ответов: 5968
Web-сайт:
Профиль | | #3
Добавлено: 21.11.05 08:23
А смысл? Не лучше ли для коммуникации юзать .NET Remoting или скажем
сокеты?
Номер ответа: 4
Автор ответа:
student-uni
Вопросов: 122
Ответов: 257
Профиль | | #4
Добавлено: 21.11.05 23:29
Сокеты уже обсуждали.
недостатки:
- Необходимо иметь ТСПип
- необходимо как то сообщить клиенту, какой Ай Пи выбрал сервер
- небезопасно
- иногда медленновато
По .NET Remoting примеров не видел.
С интересом посмотрел бы
Номер ответа: 5
Автор ответа:
Neco
ICQ: 247906854
Вопросов: 133
Ответов: 882
Web-сайт:
Профиль | | #5
Добавлено: 26.11.05 04:40
сокеты совсем не то.
Приплюсуй ещё файеры и подозрительность админов навороченных фирм когда при сдаче проги говоришь им "а вот разрешите моей проге доступ к сети".
А где тут гениальность и крутявость NET?
Обычные апишки - их можно где угодно набросать, разве нет?
Я думал что-то встроенное увижу...
(c) Промокашка:
"Ха! Это и я так могу!"
8)
Номер ответа: 6
Автор ответа:
Павел
Администратор
ICQ: 326066673
Вопросов: 368
Ответов: 5968
Web-сайт:
Профиль | | #6
Добавлено: 26.11.05 09:59
Неужто соображения секьюрити не позволяют программам по TCP обзаться с 127.0.0.1? Я этого представить не могу.
Из встроенных средств .NET, целиком и полностью предназначенных для обеспечения свяи между разными доменами приложения, процессами, компьютерами - это технология .NET Remoting.
Апишки... Да, они имеют право на существование. Но во-первых, когда есть специально преназначенные средства, лучше использовать их - к тому же, если они намного удобнее в использовании. Во-вторых, если вдруг понадобится кроссплатформенность, то Remoting (как и сокеты) будет работать везде, где есть реализация .NET Framework (сейчас - например в Mono для Linux).
Номер ответа: 7
Автор ответа:
⊗WaX⊗
Вопросов: 26
Ответов: 325
Web-сайт:
Профиль | | #7
Добавлено: 27.11.05 00:22
Сам Не пробовал, но не отключенный Windows firewall в принципе должен обрубить (правда насчет localhost'a не уверен нужно попробовать), а User не имеет прав разблокировать запрещенную прогу, зачастую администраторы и разработчики совершенно разные и даже противоположные по характеру люди так что возможен гимор...
Номер ответа: 8
Автор ответа:
student-uni
Вопросов: 122
Ответов: 257
Профиль | | #8
Добавлено: 28.11.05 00:53
Net Remoting .... а у кого есть рабочий пример ? На мой взгляд вышеприведенный пример функционирует весьма неплохо.
Спасибо заранее.
Номер ответа: 9
Автор ответа:
Павел
Администратор
ICQ: 326066673
Вопросов: 368
Ответов: 5968
Web-сайт:
Профиль | | #9
Добавлено: 28.11.05 03:41
Примеры в MSDN и .NET Framework SDK.
Номер ответа: 10
Автор ответа:
Павел
Администратор
ICQ: 326066673
Вопросов: 368
Ответов: 5968
Web-сайт:
Профиль | | #10
Добавлено: 28.11.05 04:17
2 WaX: у меня неотключенный виндовый файрвол (из XP SP2) нисколько не ругается на сетевую активность в зоне локального компьютера.
Номер ответа: 11
Автор ответа:
⊗WaX⊗
Вопросов: 26
Ответов: 325
Web-сайт:
Профиль | | #11
Добавлено: 29.11.05 23:08
2 Pavel
Конкретная задача
Написоно две программы.
В одной из ДатаГрида выбирается номер детали и воводится инфа.
Следом открывается следующая программа (Alt-Tab'ом)
юзеры захотели чтобы при переключении окна во второй проге автоматом выбирался номер детали данные по которому только что вводили в первой.
И что из-за такой мелочи пришлось городить огород с Remoting из пушки по воробьям ИМХО.
А что Firewall не ругается круто, но ИМХО не правильно - Outpost заругался