Ir ao conteúdo

Posts recomendados

Postado

eis a declaração do CopyMemory() no VB6:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

a minha questão é: como se usa o CopyMemory() corretamente?
eu já tentei usar, mas sem sorte:
 

Option Explicit

Private Declare Sub GetDWord Lib "MSVBVM60.dll" Alias _
"GetMem4" (ByRef inSrc As Any, ByRef inDst As Long)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

'Gets the address variable value:
Private Function DeRef(ByVal inPtr As Long) As Long
    If (inPtr) Then Call GetDWord(ByVal inPtr, DeRef)
End Function

Private Sub Form_Load()
    Dim MyVar As Long, MyPtr As Long
    MyVar = 12345 ' Set a variable value
    MyPtr = VarPtr(MyVar) ' Get a pointer to variable
    Debug.Print DeRef(MyPtr) ' De-reference - Prints "12345": prints the address variable value
    
    'copy the '24' value to address variable:
    Call CopyMemory(DeRef(MyPtr), 24, Len(MyVar))
    Debug.Print DeRef(MyPtr)
End Sub

o 'DeRef() é para obter o valor da variável endereçada;
o VarPtr() é para obter o endereço da variável.
o meu objetivo, agora, é criar 1 classe Ponteiros para usar em VB6. assim posso obter, por exemplo, 1 array de pixels do CreateBitmap() ou CreateDIBSection().
o CopyMemory() ajuda muito, mas ainda estou confuso a usar com variáveis, quanto mais com ponteiros e arrays.

Postado

@Cambalinho É só passar as variáveis com o tamanho em bytes como argumento para a Sub. Da forma que fez está errado já que o segundo parâmetro é o Source e você passou um valor constante.

 

Veja se assim resolve,

 

Call CopyMemory(MyPtr, MyVar, Len(MyVar))

 

  • Curtir 1
Postado

o problema é que o 'MyPtr' é 1 ponteiro... e este é que altera o valor de 'MyVar'... e sim usei 1 valor literal para testar...
então se o 'MyPtr' já tem  endereço de memória do 'MyVar', como posso alterar o valor do 'MyVar' usando o 'MyPtr'?

Postado

MyPtr é só uma variável do tipo Long e não um ponteiro. VB6 não tem ponteiros como a linguagem C. Para manipular dados da memória terá que usar APIs como CopyMemory.

  • Curtir 1
Postado

o varptr() é para obter o endereço da variavel
o MyPtr recebe o ponteiro.. agora como posso usar o 'MyPtr ' na CopyMemory() para alterar o valor na 'MyVar'?

Call CopyMemory(MyPtr, 12, Len(MyPtr))

o 'MyPtr' tem o endereço da variável... como faço para  CopyMemory() usar isso?

Postado
14 minutos atrás, Cambalinho disse:

o varptr() é para obter o endereço da variavel

Essa função retorna o endereço da variável, porém isso não tem nenhuma utilidade para CopyMemory.

 

16 minutos atrás, Cambalinho disse:

agora como posso usar o 'MyPtr ' na CopyMemory() para alterar o valor na 'MyVar'?

É como comentei no primeiro post.

 

Veja os parâmetros: 

CopyMemory(Destination As Any, Source As Any, ByVal Length As Long)

 

Se quer copiar o conteúdo de MyPtr para MyVar, é só passar MyVar como argumento para Destination e MyPtr para Source. O tamanho é em bytes:

 

Call CopyMemory(MyVar, MyPtr, Len(MyVar))

 

  • Curtir 1
Postado

resolvido:
 

Private Sub Form_Load()
  Dim MyVar As Long, MyPtr As Long
    MyVar = 12345 ' Set a variable value
    MyPtr = VarPtr(MyVar) ' Get a pointer to variable
    Debug.Print DeRef(MyPtr) ' De-reference - Prints "12345": prints the address variable value
    Dim MyVar2 As Long
    MyVar2 = 2000
    'copy the '24' value to address variable:
    Call CopyMemory(ByVal MyPtr, MyVar2, Len(MyVar2))
    Debug.Print MyVar

End Sub

1 - VarPtr() obtém o endereço da variável;
2 - DefRef() obtém o valor da variável endereçada;
3 - CopyMemory(ByVal PonteiroDestino, ValorOrigem, TamanhoOrigem)... ... sim 'ByVal' fez a diferença... declaração:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

o meu código usa Long, como posso fazer para aceitar outros tipos?

acabei de atualizar a class:
 

Option Explicit

Private Declare Sub GetDWord Lib "MSVBVM60.dll" Alias _
"GetMem4" (ByRef inSrc As Any, ByRef inDst As Long)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private ptr As Long

'Gets the address variable value:
Private Function DeRef(ByVal inPtr As Long) As Long
    If (inPtr) Then Call GetDWord(ByVal inPtr, DeRef)
End Function

Public Sub GetPointer(ByRef valor As Long) 'permite aceitar o sinal de igual
    ptr = VarPtr(valor)
End Sub

Public Function GetValueAddressed() As Long
    GetValueAddressed = DeRef(ptr)
End Function

Public Sub SetValue(value As Long)
     Call CopyMemory(ByVal ptr, value, Len(value))
End Sub

Public Function GetAddressed() As Variant
    GetAddressed = Hex(ptr) 'hex for get the hexadecimal values: memory addresses
End Function
  
'como a uso:
Private Sub Form_Load()
  Dim MyVar As Long
  Dim ptr As Pointer
  Set ptr = New Pointer
    MyVar = 30
    ptr.GetPointer MyVar
    ptr.SetValue 2000
    Debug.Print MyVar
End Sub

'imprimido:
'2000'

e está correto.... o problema é que só aceita long 😞

Postado
30 minutos atrás, Cambalinho disse:
Call CopyMemory(ByVal MyPtr, MyVar2, Len(MyVar2))

Por que passou o argumento destino como valor?

 

Faz mais sentido passar como referência que é o padrão do VB.

  • Curtir 1
Postado

até testei, mas a linha fica vermelha.... e isso é erro.. testei agora mesmo... é sério:

image.thumb.png.233ae7173c437d794ee074c5c454eded.png

 

image.thumb.png.4a20568f2198f3fae7d5db277eb82e7a.png

devido a ser assim que funciona.. .digo eu..
posso usar o tipo 'variant' ou 'object' para aceitar qualquer tipo de dados?

Postado

Acho que está fazendo confusão.

 

O primeiro argumento de CopyMemory deve ser a variável que vai receber o conteúdo da outra (Source).

 

Para isso não use ByVal, apenas passe as variáveis como argumento, p.ex,

 

Sub Teste()
    Dim Origem  As Long
    Dim Destino As Long
    
    Origem = 123
    
    Call CopyMemory(Destino, Origem, Len(Origem))
    
    Debug.Print Destino
    
End Sub

 

Assim todos os argumentos são ByRef por padrão.

 

Se o primeiro argumento fosse o endereço da variável, poderia ser ByVal, mas essa função não é necessária.

 

Call CopyMemory(ByVal VarPtr(Destino), Origem, Len(Origem))

 

  • Amei 1
Postado

muito obrigado pela correção.
agora preciso de atualizar: posso usar o tipo 'variant' ou isso?

estou a testar isto:
 

Private Sub Form_Load()
  Dim MyVar As Long
  Dim name As String
  Dim s As String
  name = "joaquim"
  MyVar = VarPtr(name)
  s = "joao"
  CopyMemory ByVal (MyVar), s, LenB(s)
  
  Debug.Print name
End Sub

o resultado é: '??' e nem sei o motivo 😞

Postado

agora o string funciona:

Option Explicit

Private Declare Sub GetDWord Lib "MSVBVM60.dll" Alias _
"GetMem4" (ByRef inSrc As Any, ByRef inDst As Long)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public ptr As Long

'Gets the address variable value:
Private Function DeRef(ByVal inPtr As Long) As Long
    If (inPtr) Then Call GetDWord(ByVal inPtr, DeRef)
End Function

Public Sub GetPointer(ByRef valor As Long)
    ptr = VarPtr(valor)
End Sub

Public Sub GetPointerString(ByRef valor As String)
    ptr = StrPtr(valor)
End Sub

Public Function GetValueAddressed() As Long
    If (ptr = 0) Then Exit Function
    GetValueAddressed = DeRef(ptr)
End Function

Public Sub SetValue(value As Long)
    If (ptr = 0) Then Exit Sub
     Call CopyMemory(ByVal ptr, value, Len(value))
End Sub

Public Sub SetStringValue(value As String)
    If (ptr = 0) Then Exit Sub
     CopyMemory ByVal (ptr), ByVal StrPtr(value), LenB(value)
End Sub

Public Function GetAddressed() As Long
    If (ptr = 0) Then GetAddressed = 0
    GetAddressed = Hex(ptr) 'hex for get the hexadecimal values: memory addresses
End Function

com uso(sempre me esqueço do 'set nomevaraivel = new tipo' kkkk)
 

Private Sub Form_Load()
    Dim MyVar As String
    Dim ptr As Pointer
    Set ptr = New Pointer
    MyVar = "joaquim Miguel Cambarinho de Jesus"
    ptr.GetPointerString MyVar
    ptr.SetStringValue "hello world"
    Debug.Print MyVar
End Sub

resultado:
"hello worlduel Cambarinho de Jesus"
o que não sei:
1 - é possível juntar a função GetPointer()  e GetPointerString() numa? e será que posso usar double e float?
2 - ainda não sei usar os arrays... se tiver algumas dicas, por favor diga

Postado

e consegui:
 

Public ptr As Long
  
Public Sub GetPointer(ByRef valor As Variant)
    'Debug.Print TypeName(valor)
    If (TypeName(valor) = "Long") Then
        ptr = VarPtr(valor)
    ElseIf (TypeName(valor) = "String") Then
        ptr = StrPtr(valor)
    End If
End Sub

 Public Sub SetValue(value As Variant)
    If (ptr = 0) Then Exit Sub
    If (TypeName(value) = "Long") Then
        Call CopyMemory(ByVal ptr, value, Len(value))
    ElseIf (TypeName(value) = "String") Then
       CopyMemory ByVal (ptr), ByVal StrPtr(value), LenB(value)
    End If
End Sub

mas ainda me falta corrigir  este código:
 

Private Declare Sub GetDWord Lib "MSVBVM60.dll" Alias _
"GetMem4" (ByRef inSrc As Any, ByRef inDst As Any)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)



'Gets the address variable value:
Private Function DeRef(ByVal inPtr As Long) As Long
    If (inPtr) Then Call GetDWord(ByVal inPtr, DeRef)
End Function

Public Function GetValueAddressed() As Long
    If (ptr = 0) Then Exit Function
    GetValueAddressed = DeRef(ptr)
End Function

ainda não percebi como posso alterar estas funções para usar String 😞

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...