2012-08-03 62 views
2

我在這裏有一個問題:我試圖將一個VB6字符串傳遞給用C編寫的函數,但我認爲它與LPSTR不同。當該函數被調用時,我的VB6 IDE崩潰。如何將VB字符串作爲參數傳遞給C中的函數?以下是我的代碼。感謝所有:如何將VB字符串參數傳遞給用C語言編寫的函數?

VB6

Private Declare Function WritestStr Lib 「teststr.dll」 (ByRef mystr As String) As Long 

Private Sub command1_Click() 

    Dim mystr as string 

    Call WritestStr(mystr) 
    Msgbox mystr 

End Sub 

VC6

include 「windows.h」 

Int __stdcall WritestStr(LPSTR *mystr) 
{ 
    *mystr = 「Venancio Guedes」; 
    return 0; 
} 

回答

3

它已經因爲我寫VB/Win32函數聲明劫,但我相當肯定,我記得,在默認情況下,所有參數都VB6中的外部庫函數通過byref傳遞;但是,VB6字符串類型已經是基於指針的類型,因此已經傳遞給byref的byref參數會將錯誤值推入堆棧。這會導致引用在DLL內部發生崩潰。嘗試傳遞它ByVal,相反,因爲參數的「值」實際上是字符串指針本身,這是DLL函數期望的。

正如我所說,自從我寫這些類型的聲明以來,這是一個looong時間,所以所有的標準警告都適用,但我很確定這很接近。

祝你好運!

編輯 DLL函數的ByVal聲明是正確的。現在的修復應該是您初始化/調用DLL函數用空格之前分配的字符串,如:

Dim vbString as String 
Dim result as Long 
vbString = Space$(255) ' just make sure this number is large enough 
result = WritestStr(vbString) 
+0

我試圖通過vb中的ByVal語句,如你所說,但仍然戰鬥,顯示沒有錯誤只是鎖定和關閉IDE,我使用了一個int而不是字符串,它工作完美我剛剛使用字符串 – 2012-08-03 14:34:50

+0

在您致電該函數(與字符串通過ByVal),初始化它類似於我添加到上面的解決方案... – 2012-08-03 14:56:25

+0

如果這可以解決您的問題,我可能會問你「接受」的答案,如果你願意... – 2012-08-03 16:15:09

2

VB串被稱爲OLE文檔中BSTR,並與LPWSTR幾乎兼容。它們以空字符結束每個字符的Unicode(UTF-16)字符串2個字節,但在字符串指針指向的內存之前有一個32位長度。

您的代碼使用LPSTR *,它是指向每個字符ANSI字符串1個字節的指針。顯然,你這樣做是爲了將你的字符串返回給VB6代碼。

不幸的是,這兩個是不兼容的。

爲什麼代碼崩潰的原因是要傳遞VB6的變量< myStr中>你的功能,但默認情況下它被設置爲vbNullString,這就好比:

BSTR mystr = NULL; 

但你的主要問題是VB不可能像你寫的那樣使用你的C函數。沒有辦法爲LPSTR *編寫Declare語句。如果你改變了你的C代碼

include 「windows.h」 

Int __stdcall WritestStr(LPSTR mystr) 
{ 
    const LPSTR myconststr = 「Venancio Guedes」; 

    if (mystr) 
     int destlen = strlen(mystr); 
     int srclen = strlen(myconststr); 
     if (destlen >= srclen) 
     { 
      strcpy(mystr, myconststr); 
      return 0; 
     } 
    return srclen; 
} 

...你可以改變申報:

Private Declare Function WritestStr Lib 「teststr.dll」 (ByVal mystr As String) As Long 

...並確保你聲明的緩衝區以接受字符串。 你可以寫一個聲明語句爲LPSTR,但你需要

Private Sub command1_Click() 

    Dim mystr As string 
    Dim nLen As Long 

    mystr = Space$(1024) 
    nLen = WritestStr(mystr) 

    Msgbox Left$(mystr, nLen) 

End Sub 

這很容易讓人想起的大多數Win32 API函數是如何工作的。

將mystr傳遞爲ByVal通知VB6它必須將<mystr>從BSTR複製到臨時LPSTR,並將指針傳遞給該緩衝區。當它完成WriteStr()的執行後,它將LPSTR緩衝區複製回原來的BSTR。

分配一個VB字符串緩衝區<mystr>傳遞給你的函數給你一些東西寫回。

或者,您可以重寫您的C程序以便本機接受BSTR(如果您想使用多種語言,則爲最簡潔便攜的解決方案)。在這種情況下,您的原始VB6聲明將站立,即ByRef mystr As String。不幸的是,你仍然需要像在這裏一樣寫入緩衝區。

如果你想擁有LPWSTR *,LPSTR *或BSTR *,你必須在類型庫中聲明你的函數 - 我沒有時間在這裏討論。

+0

謝謝大家我在微軟網站上有這樣一個下面的鏈接http://support.microsoft.com/kb/187912/pt-br – 2012-08-04 17:02:01

+0

好吧,有一個謝謝你,我們一定會感激! – 2012-08-06 07:21:34

+0

首先,這是否工作?我真的花時間創建一個C++ DLL來測試我上面所說的。對於David W的應有的尊重,我看不出他的解決方案如何與你給我們的代碼一起工作。 LPSTR *將不能用作將字符串傳遞迴VB的方式。 – 2012-08-06 07:24:47

相關問題