16,555
社区成员
发帖
与我相关
我的任务
分享
' * * * ---== VB6.0 StandardCall DLL 模板 ==--- * * *
Option Explicit
' 在这后面写上你所需要的数据类型、变量、常量、API等声明
' - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Private Sub Main(): End Sub '请不要修改或删除这一行!!!
' - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'在这后面写上你的其它 Sub/Function ,或者全部写到其它模块中
Function Test1(ByVal a As Long, ByVal b As Long) As Long
Test1 = (a + b)
End Function
Function Test2(ByVal s As String) As String
Test2 = s
End Function
并在生成时DLL选择了输出该2个函数。DLL生成成功!Imports System.Runtime.InteropServices
Module Module1
<DllImport("E:\vb\1\StdDLL.dll", CharSet:=CharSet.Auto, SetLastError:=False)> Private Function Test1(ByVal a As Integer, ByVal b As Integer) As Integer
End Function
<DllImport("E:\vb\1\StdDLL.dll", CharSet:=CharSet.Auto, SetLastError:=False)> Private Function Test2(ByVal s As String) As String
End Function
Sub Main()
MsgBox(Test1(1, 2))
MsgBox(Test2("1234567890"))
End Sub
End Module
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
Private Sub Form_Load()
Dim p As String
Dim n As Long
Dim r As Long
p = String(10, "1")
n = Len(p) * 2
r = Test2("123", StrPtr(p), n)
p = Left(p, r)
End Sub
Function Test2(ByVal s As String, ByVal retstrbuf As Long, ByRef bufsize) As Long
Dim s2 As String
Dim n As Long
Dim b() As Byte
s2 = "新字符串" & s & Chr(0)
n = LenB(s2)
If n < bufsize Then
b = StrConv(s2, vbFromUnicode)
CopyMemory retstrbuf, StrPtr(s2), n
End If
bufsize = n
Test2 = n / 2 - 1
End Function
<DllImport("E:\vb\1\StdDLL.dll", CharSet:=CharSet.unicode, SetLastError:=False)> Private Function Test2(ByVal s As String,byval buf as int32,byref n as int32) As int32
End Function
Dim p1 As IntPtr
Dim s1 As String
Dim n1 As Int32
Dim r1 As Int32
p1 = Runtime.InteropServices.Marshal.AllocHGlobal(20)
s1 = "123"
n1 = 20
r1 = Test2(s1, p1, n1)
s1 = Runtime.InteropServices.Marshal.PtrToStringUni(p1)
Runtime.InteropServices.Marshal.FreeHGlobal(p1) <DllImport("E:\vb\1\StdDLL.dll", CharSet:=CharSet.Unicode, SetLastError:=False, CallingConvention:=CallingConvention.StdCall)> Private Function Test2(ByVal s As String) As String
End Function
Sub Main()
MsgBox(Test2("123"))
End Sub
运行后,现象仍然。
-----------------------------
问题签名:
问题事件名称: APPCRASH
应用程序名: DLL.vshost.exe
应用程序版本: 12.0.30723.0
应用程序时间戳: 53cf4fe5
故障模块名称: StackHash_9c18
故障模块版本: 6.3.9600.16384
故障模块时间戳: 52159015
异常代码: c0000374
异常偏移: PCH_AF_FROM_ntdll+0x000E2F68
OS 版本: 6.3.9600.2.0.0.272.7
区域设置 ID: 2052
其他信息 1: 9c18
其他信息 2: 9c18f3d00532e1ac4ad8a8d10959dbaf
其他信息 3: 2804
其他信息 4: 2804869cfe42e0b763794f562ffeb373
联机阅读隐私声明:
http://go.microsoft.com/fwlink/?linkid=280262
如果无法获取联机隐私声明,请脱机阅读我们的隐私声明:
C:\Windows\system32\zh-CN\erofflps.txt
Function Test2(ByVal s As long, ByVal retstrbuf As Long, ByRef bufsize) As Long
Dim s2 As String
Dim n As Long
Dim b() As Byte
n=lstrlenW(s)
s2=string(n+1,0)
copymemory strptr(s2),s,n*2
s2=left(s2,n)
'之前传地址,后面正常操作string类型
s2 = "新字符串" & s2 & Chr(0)
n = LenB(s2)
If n < bufsize Then
b = StrConv(s2, vbFromUnicode)
CopyMemory retstrbuf, StrPtr(s2), n
End If
bufsize = n
Test2 = n / 2 - 1
End Function
Dim p2 As IntPtr = Marshal.StringToBSTR("abc")
上面vb代码不改,改下.net的第一个参数的声明,应该也不会出问题,内存非法访问可能是vb访问了字符串变量的前4个地址来求长度
<DllImport("E:\vb\1\StdDLL.dll", CharSet:=CharSet.unicode, SetLastError:=False)> Private Function Test2(ByVal s As intptr,byval buf as int32,byref n as int32) As int32
End Function