如何用PowerShell脚本调用带LPINT参数的C++ DLL函数MyFunction
解决方案:传递int类型的引用给LPINT参数
方法1:使用C#的ref关键字修改DllImport签名
这种方法最直观,直接对应C++的LPINT(int*)类型,无需手动处理内存分配。
修改后的PowerShell脚本:
Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class CFunctions { [DllImport("D:\\Test\\MySample.dll", CallingConvention = CallingConvention.Cdecl)] // 将IntPtr替换为ref int,直接匹配LPINT(int*)类型 public static extern int MyFunction(ref int a, string data, ref int b); } "@ # 调用函数时用[ref]传递变量的引用 $x = 21 $data_string = "Hello" $y = 0 # 通过[ref]传递x和y的内存地址,对应C++的int*参数 $result = [CFunctions]::MyFunction([ref]$x, $data_string, [ref]$y) Write-Output "MyFunction return: $result" Write-Output "修改后的x值: $x" Write-Output "函数输出的y值: $y"
说明:
ref int在C#中直接对应C++的int*(LPINT),CLR会自动处理地址传递逻辑。- 如果第三个参数
b是仅输出(函数只写入值,不读取输入),可以把签名改成out int b,调用时同样用[ref]$y即可,语义更明确。
方法2:手动分配非托管内存(适合精细控制内存的场景)
如果需要手动管理内存生命周期,可以借助Marshal类分配非托管内存,完成数据拷贝与读取。
示例脚本:
Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class CFunctions { [DllImport("D:\\Test\\MySample.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int MyFunction(IntPtr a, string data, IntPtr b); } "@ $x = 21 $data_string = "Hello" $y = 0 # 分配非托管内存存储x的初始值 $ptrX = [System.Runtime.InteropServices.Marshal]::AllocHGlobal([System.Int32]::Size) [System.Runtime.InteropServices.Marshal]::WriteInt32($ptrX, $x) # 分配非托管内存存储y的初始值 $ptrY = [System.Runtime.InteropServices.Marshal]::AllocHGlobal([System.Int32]::Size) [System.Runtime.InteropServices.Marshal]::WriteInt32($ptrY, $y) # 传递内存地址调用函数 $result = [CFunctions]::MyFunction($ptrX, $data_string, $ptrY) # 读取非托管内存中修改后的值 $updatedX = [System.Runtime.InteropServices.Marshal]::ReadInt32($ptrX) $updatedY = [System.Runtime.InteropServices.Marshal]::ReadInt32($ptrY) # 释放非托管内存,避免内存泄漏 [System.Runtime.InteropServices.Marshal]::FreeHGlobal($ptrX) [System.Runtime.InteropServices.Marshal]::FreeHGlobal($ptrY) Write-Output "MyFunction return: $result" Write-Output "修改后的x值: $updatedX" Write-Output "函数输出的y值: $updatedY"
说明:
AllocHGlobal用于分配指定大小的非托管内存,WriteInt32将托管变量的值写入该内存区域。- 调用函数后通过
ReadInt32读取非托管内存中的结果,最后必须用FreeHGlobal释放内存。
内容的提问来源于stack exchange,提问作者Susjaisw
相关产品推荐
相关产品推荐

