Sto cercando di chiamare una DLL scritta in C ++ da un'applicazione VB6.
Ecco il codice di esempio C ++ per chiamare la DLL.
char firmware[32];
int maxUnits = InitPowerDevice(firmware);
Tuttavia, quando provo a chiamarlo da VB6 ottengo l'errore bad DLL calling convention
.
Public Declare Function InitPowerDevice Lib "PwrDeviceDll.dll" (ByRef firmware() As Byte) As Long
Dim firmware(32) As Byte
InitPowerDevice(firmware)
Modifica: il prototipo 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[]);
risposte:
3 per risposta № 1È passato molto tempo, ma penso che sia necessario modificare anche la funzione C per essere 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)
Non credo che VB6 supporti la chiamata cdecl
funziona in modo normale - potrebbero esserci degli hack per farlo. Magari puoi scrivere un wrapper dll
che avvolge il cdecl
funzione con a stdcall
funzione e inoltra semplicemente la chiamata.
Questi sono alcuni hack - ma non l'ho provato.
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 per risposta № 2
È necessario passare un puntatore all'inizio del contenuto dell'array, non un puntatore a SAFEARRAY.
Forse quello di cui hai bisogno è:
Public Declare Function InitPowerDevice Lib "PwrDeviceDll.dll" ( _
ByRef firmware As Byte) As Long
Dim firmware(31) As Byte
InitPowerDevice firmware(0)
o
Public Declare Function InitPowerDevice CDecl Lib "PwrDeviceDll.dll" ( _
ByRef firmware As Byte) As Long
Dim firmware(31) As Byte
InitPowerDevice firmware(0)
La parola chiave CDecl funziona solo in un programma VB6 compilato in codice nativo. Non funziona mai nell'IDE o negli EXE codice p.
0 per risposta № 3
Poiché il tuo errore è "convenzione di chiamata non valida", dovresti provare a modificare la convenzione di chiamata. Uso del codice C. __cdecl
di default, e IIRC VB6 aveva un Cdecl
parola chiave che potresti usare con Declare Function
.
Altrimenti puoi cambiare il codice C da usare __stdcall
oppure crea una libreria dei tipi (.tlb) con le informazioni sul tipo e la convenzione di chiamata. Potrebbe essere meglio di Declare Function
perché si utilizzano i tipi di dati C durante la definizione della libreria dei tipi, ma VB6 li riconosce bene.
Per quanto riguarda il tipo di argomento, firmware() As Byte
con ByVal
(non ByRef
) dovrebbe andare bene.