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)

cdeclVB6は通常の方法で関数を呼び出すことをサポートしていないと思います-それを行うためのハックがあるかもしれません。関数を関数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デフォルトで使用され、IIRCVB6Cdeclにはで使用できるキーワードがありましDeclare Functionた。

それ以外の場合は、使用するCコードを変更する__stdcallか、型情報と呼び出し規約を使用して型ライブラリ(.tlb)を作成できます。タイプライブラリを定義するときにCデータ型を使用するよりも良いかもしれませんがDeclare Function、VB6はそれらを問​​題なく認識します。

引数の型に関する限り、firmware() As Bytewith ByVal(not ByRef)は問題ないはずです。

于 2012-12-17T16:22:43.293 に答える