VB.NET和C++应用程序加载C++实现的DLL

C++应用程序 xxx.cpp:

#include "framework.h" //必须的头文件在消息循环中, WM_CREATE 消息中进行加载和调用,因为我们的DLL需要当前窗口句柄作为参数,所以这里也需要传递这个参数 hWnd

需要添加 WM_COPYDATA 消息判断,因为在dll中是通过窗口句柄和 WM_COPYDATA 消息进行数据传递的

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    switch (message)    {    case WM_CREATE: {        HMODULE hDll = LoadLibrary(L"get_computer_message.dll");        if (hDll) {            typedef BOOL(*START_MONITOR)(HWND);            START_MONITOR StartMonitor = (START_MONITOR)GetProcAddress(hDll, "StartMonitoring");            if (StartMonitor) { StartMonitor(hWnd);  //句柄不能是 HWND hMainWnd = GetForegroundWindow(); 直接使用传递过来的 hWnd            }        }        eventLogs.push_back(L"text");        SendMessageW(g_hList, LB_ADDSTRING, 0, (LPARAM)L"text2");    }        break;    case WM_COPYDATA: {        PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;        if (pcds->dwData == EVENT_SYSTEM_FOREGROUND) {            LPCWSTR text = (LPCWSTR)pcds->lpData;            eventLogs.push_back(text);            wchar_t debugMsg[512];            swprintf(debugMsg, _countof(debugMsg), L"Received event: 0x%X, Data: %s",                pcds->dwData, (wchar_t*)pcds->lpData);            OutputDebugStringW(debugMsg);            SendMessageW(g_hList, LB_ADDSTRING, 0, (LPARAM)text);     ScrollListBoxToBottom(g_hList); //滚动列表到底部        }        return TRUE;    }    case WM_COMMAND:        {        break;    case WM_PAINT:        break;    case WM_DESTROY:        PostQuitMessage(0);        break;    default:        return DefWindowProc(hWnd, message, wParam, lParam);    }    return 0;}

vb.net 中 form1.vb :

在VB中调用dll比较复杂,但也比较简单,需要先进行dll定义

需要在

Public Class Form1

类中进行如下定义:

StartMonitorDelegate 委托调用

LoadLibrary 加载dll

GetProcAddress 获取dll中方法地址

GetModuleFileName 获取模块名称

FreeLibrary 释放dll

' 声明与DLL函数匹配的委托(显式指定调用约定)

<UnmanagedFunctionPointer(CallingConvention.StdCall)>

Private Delegate Function StartMonitorDelegate(ByVal hWnd As IntPtr) As Boolean

<DllImport("kernel32.dll", CharSet:=CharSet.Unicode)>

Private Shared Function LoadLibrary(ByVal lpFileName As String) As IntPtr

End Function

<DllImport("kernel32.dll")>

Private Shared Function GetProcAddress(ByVal hModule As IntPtr, ByVal lpProcName As String) As IntPtr

End Function

<DllImport("kernel32.dll", CharSet:=CharSet.Unicode)>

Private Shared Function GetModuleFileName(ByVal hModule As IntPtr, ByVal lpFilename As StringBuilder, ByVal nSize As Integer) As Integer

End Function

<DllImport("kernel32.dll")>

Private Shared Function FreeLibrary(ByVal hModule As IntPtr) As Boolean

End Function

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

中进行dll加载

Dim hDll As IntPtr = LoadLibrary("get_computer_message.dll")

If hDll <> IntPtr.Zero Then

    Dim procAddress As IntPtr = GetProcAddress(hDll, "StartMonitoring")

    ' 将指针转换为委托

    Dim StartMonitor As StartMonitorDelegate =

        CType(Marshal.GetDelegateForFunctionPointer(procAddress, GetType(StartMonitorDelegate)),

              StartMonitorDelegate)

    ' 调用DLL函数 传入窗口句柄

    Dim result As Boolean = StartMonitor(Me.Handle)

    If result Then

        TextBox1.AppendText("事件钩子DLL加载并启动成功!" & Environment.NewLine)

        ' 获取DLL路径

        Dim dllPath As New StringBuilder(260)

        GetModuleFileName(hDll, dllPath, dllPath.Capacity)

        TextBox1.AppendText("加载DLL成功!路径: " & dllPath.ToString() & Environment.NewLine)

        TextBox1.AppendText("函数地址: " & procAddress.ToInt64() & Environment.NewLine)

    Else

        TextBox1.AppendText("事件钩子DLL加载成功但启动失败!" & Environment.NewLine)

    End If

Else

    MessageBox.Show("加载DLL失败!")

End If

在消息循环中进行数据处理:

Dim textResult = Await SendTextToServer("电脑," & data)  方法需要进行网络请求,所以这里使用异步任务进行处理

Protected Overrides Sub WndProc(ByRef m As Message)

    If m.Msg = WM_COPYDATA Then '获取来自DLL的消息 这里获取所有的事件消息,所以这里要处理WM_COPYDATA消息

        '处理来自DLL的消息

        Dim cds As COPYDATASTRUCT = Marshal.PtrToStructure(Of COPYDATASTRUCT)(m.LParam)

        If cds.dwData.ToInt32() = EVENT_SYSTEM_FOREGROUND Then

            Dim data As String = Marshal.PtrToStringAuto(cds.lpData)

            TextBox1.AppendText("获取到电脑事件: " & data & Environment.NewLine)

            ' 发送文本信息到服务器

            ' 启动异步任务

            ' 启动异步任务处理

            Task.Run(Async Function()

                        Try

                            Dim textResult = Await SendTextToServer("电脑," & data)

                            Me.Invoke(Sub()

                                          TextBox1.AppendText("本地服务数据保存状态: " & textResult & Environment.NewLine)

                                      End Sub)

                        Catch ex As Exception

                            Me.Invoke(Sub()

                                          TextBox1.AppendText("发送失败: " & ex.Message & Environment.NewLine)

                                      End Sub)

                        End Try

                    End Function)

        End If

    End If

    MyBase.WndProc(m) '必须调用 MyBase.WndProc 以保证消息链正常传递

End Sub

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容