我正在尝试从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[]);
答案 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
)应该没问题。