什么是VB6等效的C ++ char数组?

时间:2012-12-17 15:48:17

标签: c++ dll vb6 char

我正在尝试从VB6应用程序调用用C ++编写的DLL。

这是用于调用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[]);

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

您需要将指针传递给数组内容的开头,而不是指向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中工作。

答案 2 :(得分:0)

由于您的错误是“错误的调用约定”,您应该尝试更改调用约定。默认情况下,C代码使用__cdecl,而IIRC VB6有一个Cdecl关键字可用于Declare Function

否则,您可以更改C代码以使用__stdcall,或者使用类型信息和调用约定创建类型库(.tlb)。这可能比Declare Function更好,因为在定义类型库时使用C数据类型,但VB6可以很好地识别它们。

就参数类型而言,firmware() As Byte ByVal(不是ByRef)应该没问题。