2012-12-17 56 views
0

我想從VB6應用程序調用C++編寫的DLL。什麼是C++ char數組的VB6等價物?

下面是調用該DLL的C++代碼示例。

char firmware[32]; 
int maxUnits = InitPowerDevice(firmware); 

但是,當我嘗試從VB6調用它時,出現錯誤bad DLL calling convention

Public Declare Function InitPowerDevice Lib "PwrDeviceDll.dll" (ByRef firmware() As Byte) As Long 

Dim firmware(32) As Byte 
InitPowerDevice(firmware) 

編輯:C++函數原型:

Name: InitPowerDevice 
Parameters: firmware: returns firmware version in ?.? format in a character string (major revision and minor revision) 
Return: >0 if successful. Returns number of Power devices connected 

CLASS_DECLSPEC int InitPowerDevice(char firmware[]); 
+0

這是伸展我的記憶中了一點,但它是不是BYVAL x作爲字符串? – PeteH

+0

@PeteH:我試過了,它也沒有工作。 –

+1

你能找到那個'CLASS_DECLSPEC'宏的定義嗎? –

回答

3

是一個很長一段時間,但我認爲你還需要改變你的C函數是STDCALL。

// In the C code when compiling to build the dll 
CLASS_DECLSPEC int __stdcall InitPowerDevice(char firmware[]); 

' VB Declaration 
Public Declare Function InitPowerDevice Lib "PwrDeviceDll.dll" _ 
     (ByVal firmware As String) As Long 

' VB Call 
Dim fmware as String 
Dim r as Long 
fmware = Space(32) 
r = InitPowerDevice(fmware) 

我不認爲VB6支持調用任何正常的方式cdecl功能 - 有可能是做黑客。也許你可以編寫一個包裝dll,它將cdecl功能與stdcall功能包裝在一起,並且只是轉發呼叫。

這些都是一些黑客 - 但我還沒有嘗試過。

http://planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=49776&lngWId=1

http://planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=62014&lngWId=1

+0

不幸的是同樣的錯誤。 –

+0

@JohnSmith你可以給你的C函數的原型嗎? – user93353

+0

當然可以。我會將其編輯到原始文章中。 –

0

由於您的錯誤是 「壞的調用約定」,你應該嘗試改變調用約定。 C代碼默認使用__cdecl,而IIRC VB6有Cdecl關鍵字,您可以使用Declare Function

否則,你可以改變C代碼使用__stdcall,或創建一個類型庫(.tlb)與類型信息和調用約定。這可能比Declare Function更好,因爲在定義類型庫時使用了C數據類型,但VB6可以很好地識別它們。

就參數類型而言,firmware() As ByteByVal(而不是ByRef)應該沒問題。

+0

是的,我嘗試在函數聲明中使用Cdecl,但似乎也沒有幫助。試用了'ByRef','ByVal','As String'和'()As Byte'的任何組合都無濟於事。 –

+0

VB.NET允許更改調用約定。 VB6不 - 它只允許stdcall。 –

+0

離開'ByRef'只意味着'ByRef'。明確地使用它通常會更好,但兩種方式都沒有區別。 – Bob77

0

您需要將指針傳遞給數組內容的開始,而不是一個指針SAFEARRAY。

也許你需要的是兩種:

Public Declare Function InitPowerDevice Lib "PwrDeviceDll.dll" (_ 
    ByRef firmware As Byte) As Long 

Dim firmware(31) As Byte 
InitPowerDevice firmware(0) 

Public Declare Function InitPowerDevice CDecl Lib "PwrDeviceDll.dll" (_ 
    ByRef firmware As Byte) As Long 

Dim firmware(31) As Byte 
InitPowerDevice firmware(0) 

的CDECL關鍵字只能在編譯爲本地代碼VB6程序。它從不在IDE或p代碼EXE中工作。

相關問題