史萊姆論壇

返回   史萊姆論壇 > 專業主討論區 > 程式語言討論區
忘記密碼?
論壇說明

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


發文 回覆
 
主題工具 顯示模式
舊 2007-08-22, 04:00 PM   #1
mini
管理版主
 
mini 的頭像
榮譽勳章
UID - 4144
在線等級: 級別:97 | 在線時長:9849小時 | 升級還需:147小時級別:97 | 在線時長:9849小時 | 升級還需:147小時級別:97 | 在線時長:9849小時 | 升級還需:147小時級別:97 | 在線時長:9849小時 | 升級還需:147小時級別:97 | 在線時長:9849小時 | 升級還需:147小時級別:97 | 在線時長:9849小時 | 升級還需:147小時級別:97 | 在線時長:9849小時 | 升級還需:147小時
註冊日期: 2002-12-07
文章: 13340
精華: 0
現金: 26442 金幣
資產: 3024302 金幣
預設 教學 - 如何跨程式(軟體)共用 變數

這個變數個人暫且稱為 "全域記憶體變數"
其目的是
當不同的程式 要有即時效果 而共用一個變數時,即可使用此方法

語法:
'參數: 變數記憶體位址, 編號, 使用模式; 傳回通用記憶體位址
Public Function GlobalMemVar(lpVar As Long, iNO As Integer, sMode As String, vtVar As Variant) As Long
Static gMemVar() As MemVar_Data
Dim i As Integer

On Error Resume Next
    
    i = UBound(gMemVar)
    If Err.Number > 0 Then
        Err.Clear
        ReDim Preserve gMemVar(iNO)
        
    Else
        If LCase(sMode) = "c" Or LCase(sMode) = "create" Then
            If iNO <= i Then
                iNO = i + 1 '創建的號碼已使用過時...
                ReDim Preserve gMemVar(iNO)
            End If
        End If
    End If
    
    With gMemVar(iNO)
    Select Case LCase(sMode)
    Case "get", "g"
        .lAddress = GlobalLock(.hGlobal)                       '使用前要鎖住
             CopyMemory ByVal lpVar, ByVal .lAddress, .iSize  '將 變數 複製到 全域記憶體
             GlobalUnlock .hGlobal                                      '使用後解鎖
        
    Case "put", "p"
PUTMEM:
        .lAddress = GlobalLock(.hGlobal)                       '使用前要鎖住
             CopyMemory ByVal .lAddress, ByVal lpVar, .iSize  '將 變數 複製到 全域記憶體
             GlobalUnlock .hGlobal                                      '使用後解鎖
             GlobalMemVar = .lAddress
        
    Case "create", "c"
        '得到大小(byte)
        Select Case VarType(vtVar)
        Case vbByte:     .iSize = 1
        Case vbBoolean:  .iSize = 2
        Case vbInteger:  .iSize = 2
        Case vbLong:     .iSize = 4
        Case vbSingle:   .iSize = 4
        Case vbDouble:   .iSize = 8
        Case vbCurrency: .iSize = 8
        Case vbDate:     .iSize = 8
        Case 8209:       .iSize = UBound(vtVar)
        End Select
        
        .hGlobal = GlobalAlloc(GMEM_SHARE, .iSize) '配置 全域記憶體
        GoTo PUTMEM
    
    Case "free", "f"
        GlobalFree .hGlobal '釋放記憶體
             If iNO = UBound(gMemVar) And iNO > 0 Then
            ReDim Preserve gMemVar(iNO - 1)
        
        Else
            .hGlobal = 0    '清空內容
                    .lAddress = 0
            .iSize = 0
        End If
    End Select
    End With
    
End Function
※String變數 請用 Byte陣列


使用範例1
語法:
Dim ltmp As Long
GlobalMemVar VarPtr(CLng(5)), 0, "c", CLng(5) '建立一個 全域記憶體變數,內容是5,型態是 Long,編號是0
GlobalMemVar VarPtr(CLng(2)), 0, "p", CLng(2) '對剛才的編號0 全域記憶體變數,改變內容,放入 2
GlobalMemVar VarPtr(ltmp), 0, "g", ltmp       '將編號0 全域記憶體變數 內容複製出來 到變數ltmp
'所以 變數ltmp內容原本是0 執行完第三行後 變成2
使用範例2
先在[程式 A.EXE] 宣告 "全域記憶體變數" 編號0
Dim ltmp As String
GlobalMemVar VarPtr(ltmp), 0, "c", ltmp

接著程式A 使用了 [自製 B.DLL] 的函數 (名稱為 Ring0Hook)
Ring0Hook 函數之內容是
語法:
'Ring0Hook 參數需包含 lpAddress ("全域記憶體變數" 之變數位址) 及 iSize ("全域記憶體變數" 之大小※單位是 Byte)
...
Dim a As Long
CopyMemory( a, ByVal lpAddress, iSize) '複製 "全域記憶體變數" 內容到 a
a = Time
CopyMemory( ByVal lpAddress, a, iSize) ' "全域記憶體變數" 內容 變成 a內容
...
如此 程式A運行完Ring0Hook
ltmp 將等於 Time
也就是時間


至於字串如何創建
Dim b() as Byte
b = "全域記憶體變數" & Chr(0)
GlobalMemVar VarPtr(b(0)), 0, "c", b


.bas 宣告
語法:
' Global Memory Flags
Global Const GMEM_FIXED = &H0
Global Const GMEM_MOVEABLE = &H2
Global Const GMEM_NOCOMPACT = &H10
Global Const GMEM_NODISCARD = &H20
Global Const GMEM_ZEROINIT = &H40
Global Const GMEM_MODIFY = &H80
Global Const GMEM_DISCARDABLE = &H100
Global Const GMEM_NOT_BANKED = &H1000
Global Const GMEM_SHARE = &H2000
Global Const GMEM_DDESHARE = &H2000
Global Const GMEM_NOTIFY = &H4000
Global Const GMEM_LOWER = GMEM_NOT_BANKED
Global Const GHND = (GMEM_MOVEABLE Or GMEM_ZEROINIT)
Global Const GPTR = (GMEM_FIXED Or GMEM_ZEROINIT)

Public Declare Function GlobalAlloc Lib "kernel32" ( _
    ByVal wFlags As Long, _
    ByVal dwBytes As Long) As Long
Public Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Public Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Public Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Public Type MemVar_Data
    lAddress As Long
    hGlobal  As Long
    iSize    As Integer
End Type

'如果來源與目的都是 VB變數,則直接填上
'如果來源與目的 是 記憶體位址,其前方需填上 ByVal
'如果來源與目的 是 陣列,填上第一個維度 A(0)
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    lpDest As Any, _
    lpSource As Any, _
    ByVal cbCopy As Long)

以上可以將其"改造"成 PowerBasic程式碼編譯成 .dll
可用性將會很大
也可用作"監視"用途
如何發揮就看您自己

此帖於 2007-08-22 08:13 PM 被 mini 編輯. 原因: 字串創建
mini 目前線上  
送花文章: 2012, 收花文章: 8000 篇, 收花: 26804 次
回覆時引用此帖
有 3 位會員向 mini 送花:
kada (2007-09-24),nikhau (2008-02-11),飛鳥 (2007-08-22)
感謝您發表一篇好文章
發文 回覆



發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 10:22 AM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1