0

我正在尝试从 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[]);
4

3 回答 3

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包装函数并转发调用。cdeclstdcall

这些是一些技巧-但我还没有尝试过。

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

于 2012-12-17T16:16:16.477 回答
1

You need to pass a pointer to the beginning of the array contents, not a pointer to the SAFEARRAY.

Perhaps what you need is either:

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

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

or

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

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

The CDecl keyword only works in a VB6 program compiled to native code. It never works in the IDE or in p-code EXEs.

于 2012-12-17T18:58:29.813 回答
0

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

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

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

于 2012-12-17T16:22:43.293 回答