FreeBasic寫DLL給VB6調用(直接用API創建和修改VB字符串方法)

  勇芳 2018-7-2 15457

寫DLL給VB用,不是什么難題,但我們要做到字符變量,從FreeBasic到VB6,從VB6到FreeBasic,在VB6端無痛使用,那就要費點功夫了。

VB6代碼:直接寫 String
Private Declare Function GetStr Lib "FBtoVB.dll" Alias "GETSTR@0" () As String '返回字符串

FreeBasic和VB6的字符變量的內存格式是不同的,因此我們要在FreeBasic的地方搞個轉換函數。

FB代碼:
'=====================關鍵函數================
'--------------------------------------------------------------------------
Function BStrToString(nBStr As BStr) As String  '將VB里的字符串轉換為FB里使用的字符串
    Dim L As Long =Peek(Long,Cast(UInteger,nBStr) -4)
    Dim ss As String = String(L,0)
    memcpy StrPtr(ss),nBStr,L
    Function = ss
End Function
'--------------------------------------------------------------------------
Function StringToBStr(nStr As String) As BStr  '將FB里的字符串轉換為VB里使用的字符串
  Function = SysAllocString( Cast(WString Ptr, StrPtr(nStr) ) ) '偽造 VB 字符串
End Function
'--------------------------------------------------------------------------
Function BStrToStringW(nBStr As BStr) As String  '將VB里的字符串轉換為FB里使用的字符串,用于字符數組
  '注意,假如字符串里包含 chr(0) 將會在此被截斷
  Dim ss As String
  If nBStr <> 0 Then
      ss = *CPtr(WString Ptr, nBStr)
  End If
  Function = ss
End Function
'--------------------------------------------------------------------------
Sub SetBstr(ByRef nBStr As BStr,nStr As String ) ' 修改VB字符串,用于字符數組
'必須是 ByRef ,不然修改不了nBStr,默認是 ByVal
    If nBStr=0 Then 
        '無字符
        nBStr=SysAllocString(nStr) '新增字符串
    Else
        '有字符
        SysReAllocString(@nBStr,nStr) '修改字符串
    End If    
End Sub

下面是FB里的導出函數代碼,測試例題用:

'--------------------------------------------------------------------------
Function JiaFa(ByVal a As Long ,ByVal b As Long ) As Long Export  '參數全是數字例題
'ByVal 由于VB和FB默認表達不同,避免發生不一至的情況,前面的必須加個,和VB那邊一樣。
  Return a+b
End Function
'--------------------------------------------------------------------------
Sub Dizi(ByRef a As Long ) Export'以地址傳來參數
    a=666
End Sub
'--------------------------------------------------------------------------
Sub LongShuZhu(ByVal a As Long Ptr,ByVal b As Long) Export '處理VB的數組
'FB 和 VB 之間,處理數組的方式不同,因此無法直接傳數組
'只能以指針的方式處理
  For i As Long =0 To b-1
    a[i]=Rnd *10000
  Next
End Sub
'--------------------------------------------------------------------------
Function GetStr() As BStr Export  '返回字符例題
'直接將字符返回到VB里,由于VB與FB的字符內存不同,必須用轉換
  Dim a As String 
  a="返dd回dd字dd符dd例dd題dd"
  Return StringToBStr(a)
End Function
'--------------------------------------------------------------------------
Function LenDuoStr(ByVal a As BStr ,ByVal b As BStr ,ByVal c As BStr ,ByVal d As BStr ) As Long Export  '處理VB發來的字符例題
'由于VB與FB的字符內存不同,必須用轉換
  AfxMsg BStrToString(a)
  Return Len(BStrToString(b) & BStrToString(c) & BStrToString(d))
End Function
'--------------------------------------------------------------------------
Sub StrShuZhu(ByVal a As BStr Ptr ,ByVal b As Long) Export '處理VB的數組
'FB 和 VB 之間,處理數組的方式不同,因此無法直接傳數組
'只能以指針的方式處理
 Dim bb As String 
  For i As Long =0 To b-1
    bb=BStrToStringW(a[i])
    If Len(bb) Then AfxMsg bb,"讀取字符"
    SetBstr a[i],Str(Rnd *999 )
  Next
End Sub

再來看VB6這邊的DLL聲明例題:

'==============處理數字變量===================
Private Declare Function JiaFa Lib "FBtoVB.dll" Alias "JIAFA@8" (ByVal a As Long, ByVal b As Long) As Long '數字例題
'Alias 里的全部是大寫,不管FB里如何,一律大寫
'@8 標準符號,是為了兼容C語言默認帶的, 表示有2個參數,無參數是 @0 ,1個參數為 4 ,幾個就 幾個*4

Private Declare Sub Dizi Lib "FBtoVB.dll" Alias "DIZI@4" (ByRef a As Long) '傳地址數字
'以地址方式傳數字參數給FB,FB那里可以修改參數值了

Private Declare Sub LongShuZhu Lib "FBtoVB.dll" Alias "LONGSHUZHU@8" (ByVal 數組地址 As Long, ByVal 數組長度 As Long) '數組例題
'FB 和 VB 之間,處理數組的方式不同,因此無法直接傳數組,數組長度是為了FB那邊知道長度,不然超邊界了軟件會崩潰的。
'其它數字和Long 一樣處理,對應FB那邊類型名是
'VB類型:Byte  Integer Single Double
'FB類型:UByte Short   Single Double

'==============處理字符串變量===================
Private Declare Function GetStr Lib "FBtoVB.dll" Alias "GETSTR@0" () As String '返回字符串
'從FB里傳來的字符,VB這邊直接使用,無障礙。
Private Declare Function LenDuoStr Lib "FBtoVB.dll" Alias "LENDUOSTR@16" (ByVal a As String, ByVal b As String, ByVal c As String, ByVal d As String) As Long '傳字符串給FB
'傳VB的字符到FB那邊使用。注意,FB那邊中文算2個,英文算1個。
Private Declare Sub StrShuZhu Lib "FBtoVB.dll" Alias "STRSHUZHU@8" (ByVal 數組地址 As Long, ByVal 數組長度 As Long) '數組例題
'FB 和 VB 之間,處理數組的方式不同,因此無法直接傳數組,數組長度是為了FB那邊知道長度,不然超邊界了軟件會崩潰的。
'

還增加了數組的操作方法,下面是VB6調用DLL例題

Private Sub Form_Load()
    ChDrive App.Path '必須先設置軟件文件夾,否則,萬一不在EXE文件夾開啟軟件,會發生找不到DLL文件的錯誤
    ChDir App.Path

End Sub
Private Sub Command4_Click()
    Dim a As Long
    a = 100
    Dizi a
    Debug.Print a
End Sub

Private Sub Command5_Click()
 Dim a(10) As Long, i As Long

 LongShuZhu VarPtr(a(0)), UBound(a) + 1
 For i = 0 To 10
    Debug.Print a(i),
 Next
Debug.Print

End Sub

Private Sub Command6_Click()
 Dim a(10) As String, i As Long
 a(0) = "dd"
 a(2) = ""
 StrShuZhu VarPtr(a(0)), UBound(a) + 1
 For i = 0 To 10
    Debug.Print a(i),
 Next
Debug.Print
End Sub

Private Sub Command1_Click()
    Label1 = JiaFa(10, 20)
End Sub
Private Sub Command2_Click()
    Dim b As String
    b = GetStr
    Label1 = b
    Debug.Print b, Len(b)

End Sub
Private Sub Command3_Click()
    Dim a As String
    a = "w我o"
    Label1 = LenDuoStr(a, "p單位c", "", "ddd")
End Sub


勇芳編程群里,有搞好的工程源碼,感興趣的,請進群下載。


因國家互聯網安全管理要求,關閉回帖功能。大家需要留言,請使用【勇芳軟件客服】即時聯系勇芳點此打開->>勇芳軟件客服
返回
聯系勇芳
一个人看的www视频播放中文_2012中文字幕电影_亚洲国产成人高清在线观看_中文字幕天堂最新版在线网