1

簡単な質問 - 低レベルのコピー メモリ API を使用して VTable のエントリを変更することにより、クラスの上書きメソッドをテストしているところです。

バックグラウンド

私はいくつかの成功を収めており、クラスの VTable 内の 2 つのエントリが同じ署名を持っている場合はそれらを交換できます。したがって、次のようなクラス定義:

Option Explicit

Public Sub Meow()
    Debug.Print "Meow"
End Sub

Public Sub Woof()
    Debug.Print "Woof"
End Sub 

... 次のような VTable を生成します。

VTable

...そして、7 番目と 8 番目のエントリを入れ替えてcls.Meow印刷することWoofも、その逆も可能です。あるクラスの VTable のエントリを、まったく別のクラスの VTable と交換することもできます (ただしthis、 を呼び出して暗黙的なポインタを逆参照しようとしない場合Me.anything) 。

だから私は別のクラスを作ることができます

Option Explicit

Public Sub Tweet()
    Debug.Print "Tweet"
End Sub

Woof一方の動作を他方の動作と交換しますTweet。複雑すぎないので、必要に応じてコードを共有できます。

できないこと...

...しかし、クラスメソッドを標準モジュールのメソッドと交換する方法を理解していますか?

この記事に基づくと、VBA が構築されている COM 機構には、VBA が非表示にする 2 つのクラス メソッドが必要なようです。

  • 暗黙のthisポインタがあります
  • HRESULT ( typedef long)を返します。

ので、私は考えました

Public Sub Meow()

クラスモジュールClass1では、と同等です

Public Function Meow(ByVal this As LongPtr) As Long

私も試してみました

Public Function Meow(ByRef meObj As Class1) As Long
Public Function Meow(ByRef meObj As Class1) As LongPtr 'but HResult is 32 bit int
Public Sub Meow(ByVal this As LongPtr)

など。ただし、VTable からメソッドを呼び出そうとすると、VBA は常にクラッシュします。だから私は少し途方に暮れています。64 ビット コンピューターでは状況が異なるのでしょうか、それとも標準モジュール関数が呼び出しスタックに対して奇妙なことを行うのでしょうか。問題は、VTable 全体が標準モジュール関数からアセンブルされているコードの例を見たことがあるため、それが可能であることはわかっていますが、署名を正しく変換する方法がわかりません。

標準モジュールで定義されたメソッドで VTable エントリを上書きするにはどうすればよいですか?

4

1 に答える 1