News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

raiseevent of an object, in vb.net, from asm dll?

Started by Fraile, September 29, 2015, 02:45:56 AM

Previous topic - Next topic

GoneFishing

Hello ,  AsmAlmeria12
Nice  example of simple MANAGED-NATIVE  interoperability . Did you write it yoruself ?
There's no RET instruction at the end of Test proc , please edit it . I ran the example and it worked as expected

I've took your intial VB code  as a basis for researches . The problem is to raise event inside managed assembly (executables are called assemblies in .NET world  :biggrin:) from the  native DLL . It's quite a task !
It already costed me one sleepless night  :biggrin:
I'll continue my investigation but don't expect quick results from me  .



Fraile

thank very much GoneFishing, I follow investigate.

GoneFishing

I suggest to acomplish our task using slightly simplified variant  of VB.net code:
Form1.vb :

Public Class Form1

    Private WithEvents miobj As Class1
   
    Private Declare Function SomeFunc Lib "EventRaiser.dll" (ByRef X As Object) As Long
    Private Declare Function SomeOther Lib "EventRaiser.dll" (ByVal X As Object) As Long

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Call SomeFunc(miobj)
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            Call SomeOther(miobj)
    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        miobj = New Class1
        AddHandler miobj.m, AddressOf miobj.miobj_m
        AddHandler miobj.m5, AddressOf miobj.miobj_m5
        AddHandler miobj.m6, AddressOf miobj.miobj_m6
    End Sub

End Class

Public Class Class1

    Public Event m()
    Public Event M2(ByVal j As Long, ByVal r As Long)
    Public Event m3()
    Public Event m4()
    Public Event m5(ByVal j As Long, ByVal k As Long, ByVal l As Long, ByVal m As Long, ByVal n As Long, ByVal o As Long)
    Public Event m6(ByVal j As Long)
   
    Public Sub miobj_m()
        MsgBox("Event N? 1 Raised")
    End Sub
   
    Public Sub miobj_m5(ByVal j As Long, ByVal k As Long, ByVal l As Long, ByVal m As Long, ByVal n As Long, ByVal o As Long)
        MsgBox("Event N? 5 Raised, parameters: " & j & "-" & k & "-" & l & "-" & m & "-" & n & "-" & o & "-")
    End Sub

    Public Sub miobj_m6(ByVal j As Long)
        MsgBox("Event 6 Raised, parameter:" & j)
    End Sub

End Class


You see that event handling routins reside inside Class1 and declared as Public.
Doing it in such a way will increase our chances to see a Demo program in the nearest 2 months and not to become blackhats  :biggrin:

mabdelouahab

AsmAlmeria12
If you only want to apply the function "AnswerASM" You do not need to send  SubDelegateo As Delegate, Because The way to invoke it is very long
you can pass SubDelegateo As IntPtr

Declare Sub TestProc Lib "Example.dll" (ByVal SubDelegateo As IntPtr)
Secondly you must convert a delegate object to ptr you can use "Marshal.GetFunctionPointerForDelegate"
Then you can call it from your "TestProc"


        Dim RMsG As ReceptorMsG = AddressOf AnswerASM
        Dim RMsGptr As IntPtr = Marshal.GetFunctionPointerForDelegate(RMsG)
        TestProc(RMsGptr)


full vb code

Imports System.Runtime.InteropServices

Public Class Form1

    Declare Sub TestProc Lib "Example.dll" (ByVal SubDelegateo As IntPtr)

    Delegate Sub ReceptorMsG(ByVal Param1 As Integer, ByVal Param2 As String)

    Private Sub AnswerASM(ByVal Param1 As Integer, ByVal Param2 As String)
        MsgBox("Param1 =" & Param1)
        MsgBox("Param2=" & Param2)
    End Sub

    Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
        Dim RMsG As ReceptorMsG = AddressOf AnswerASM
        Dim RMsGptr As IntPtr = Marshal.GetFunctionPointerForDelegate(RMsG)

        TestProc(RMsGptr)

    End Sub
End Class


dll code

.486
.model flat,stdcall
option casemap:none
include \masm32\include\masm32rt.inc
.data
hInstance dd 0
.code
LibMain proc hInst:dword, reason:DWORD, reserved1:DWORD
    .if reason == DLL_PROCESS_ATTACH
push hInst
pop hInstance
mov eax, TRUE           
    .endif
    ret
LibMain Endp

TestProc proc IntPtr_:DWORD
invoke MessageBox,0,chr$("Masm TestProc"),0,MB_OK
p__ equ chr$("Masm Param2")
push p__
push 101
call dword ptr IntPtr_
ret
TestProc endp

End LibMain

TWell

LibMain should return TRUE?
LibMain proc hInst:dword, reason:DWORD, reserved1:DWORD
    .if reason == DLL_PROCESS_ATTACH
push hInst
pop hInstance
    .endif
    mov eax, TRUE           
    ret
LibMain Endp

GoneFishing

It turned out that this problem is all about .NET internals
Here're  several  useful links:
An Overview of Managed/Unmanaged Code Interoperability
Passing a Managed Function Pointer to Unmanaged Code
Interoperating with Unmanaged Code

Also book  ".NET 2.0 Interoperability Recipes: A Problem-Solution Approach " by Bruce Bukovics (available on books.google) - see page 173: Passing managed objects

mabdelouahab

Created by Visual Studio 2012 .net framwork 4.5 and RadAsm 2.2

Fraile