Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 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-сайт: sapfir.cift.ru
 Профиль | | #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-сайт: www.vbnet.ru
 Профиль | | #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-сайт: neco.pisem.net
 Профиль | | #5
Добавлено: 26.11.05 04:40
сокеты совсем не то.
Приплюсуй ещё файеры и подозрительность админов навороченных фирм когда при сдаче проги говоришь им "а вот разрешите моей проге доступ к сети".
А где тут гениальность и крутявость NET?
Обычные апишки - их можно где угодно набросать, разве нет?
Я думал что-то встроенное увижу...
(c) Промокашка:
"Ха! Это и я так могу!"
8)

Ответить

Номер ответа: 6
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #6
Добавлено: 26.11.05 09:59
Неужто соображения секьюрити не позволяют программам по TCP обзаться с 127.0.0.1? Я этого представить не могу.

Из встроенных средств .NET, целиком и полностью предназначенных для обеспечения свяи между разными доменами приложения, процессами, компьютерами - это технология .NET Remoting.

Апишки... Да, они имеют право на существование. Но во-первых, когда есть специально преназначенные средства, лучше использовать их - к тому же, если они намного удобнее в использовании. Во-вторых, если вдруг понадобится кроссплатформенность, то Remoting (как и сокеты) будет работать везде, где есть реализация .NET Framework (сейчас - например в Mono для Linux).

Ответить

Номер ответа: 7
Автор ответа:
 ⊗WaX⊗



Вопросов: 26
Ответов: 325
 Web-сайт: sapfir.cift.ru
 Профиль | | #7
Добавлено: 27.11.05 00:22
Неужто соображения секьюрити не позволяют программам по TCP обзаться с 127.0.0.1? Я этого представить не могу.

Сам Не пробовал, но не отключенный Windows firewall в принципе должен обрубить (правда насчет localhost'a не уверен нужно попробовать), а User не имеет прав разблокировать запрещенную прогу, зачастую администраторы и разработчики совершенно разные и даже противоположные по характеру люди так что возможен гимор...

Ответить

Номер ответа: 8
Автор ответа:
 student-uni



Вопросов: 122
Ответов: 257
 Профиль | | #8 Добавлено: 28.11.05 00:53
Net Remoting .... а у кого есть рабочий пример ? На мой взгляд вышеприведенный пример функционирует весьма неплохо.
Спасибо заранее.

Ответить

Номер ответа: 9
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #9
Добавлено: 28.11.05 03:41
Примеры в MSDN и .NET Framework SDK.

Ответить

Номер ответа: 10
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #10
Добавлено: 28.11.05 04:17
2 WaX: у меня неотключенный виндовый файрвол (из XP SP2) нисколько не ругается на сетевую активность в зоне локального компьютера.

Ответить

Номер ответа: 11
Автор ответа:
 ⊗WaX⊗



Вопросов: 26
Ответов: 325
 Web-сайт: sapfir.cift.ru
 Профиль | | #11
Добавлено: 29.11.05 23:08
2 Pavel
Конкретная задача
Написоно две программы.
В одной из ДатаГрида выбирается номер детали и воводится инфа.
Следом открывается следующая программа (Alt-Tab'ом)
юзеры захотели чтобы при переключении окна во второй проге автоматом выбирался номер детали данные по которому только что вводили в первой.
И что из-за такой мелочи пришлось городить огород с Remoting из пушки по воробьям ИМХО.

А что Firewall не ругается круто, но ИМХО не правильно - Outpost заругался

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам