Здравствуйте.
Есть некая DLL'ка и к ней инструкция. DLL скомпилирована в MS C++ 6.0. В библиотеке есть функция:
DLL Export Viewer так пишет об этой функции:
Вот как выглядит этот _vr_array_info в хедере:
А вот мой код (функции в библиотеке decorated, поэтому так странно выглядят в коде):
Все работает как полагается вплоть до вызова vr_get_array_info. По вызову vr_get_array_info AutoIt3.exe вызывает ошибку "память не может быть 'read'" ("Инструкция по адресу 0x7c93a514 обратилась к памяти по адресу 0x00000000"). При этом судя по консоли продолжает выполнение кода, но ошибка все равно всплывает.
Подскажите, пожалуйста, что я делаю не так?
Есть некая DLL'ка и к ней инструкция. DLL скомпилирована в MS C++ 6.0. В библиотеке есть функция:
Код:
Get information of disk arrays
Declaration:
VINT vr_get_array_info (VINT array_index, vr_array_info_t* pinfo);
Description:
Application can fetch the information of one specific disk array, which is located
by index of all disk arrays in current system.
Input parameters:
VINT array_index :
Index to all disk arrays in system, specify which disk array.
vr_array_info_t *pinfo :
14
Pointer to a vr_array_info_t data structure to get the information
Return value:
VR_SUCCESS :
Get the information successfully.
VR_ERR_NOT_INITED :
Raid lib hasn’t been initialized.
VR_ERR_INVALID_INDEX :
The input index is invalid.
VR_ERR_INVALID_PARAM :
Input parameter is invalid: the pointer is NULL.
DLL Export Viewer так пишет об этой функции:
Код:
Function Name : int __cdecl vr_get_array_info(int,struct _vr_array_info *)
Вот как выглядит этот _vr_array_info в хедере:
Код:
typedef struct _vr_array_info {
VWORD status; // current status of disk array
VBYTE raidType;// same as Disk_Array.raidType, but value 0xFF means
// a stand-alone disk. When it's a stand-alone disk,
// only arDevices[0] and diskNum has meaning, and diskNum should
// always be 1 .
VBYTE diskNum;// count of valid arDevices[] members.
// Note: disk array maybe incomplete, i.e. , some disk in the array maybe missing,
// corresponding device ptr arDevices[i]->pRealDevice should be NULL.
VDWORD capacityLow;// (Unit: sector)
VDWORD capacityHigh;// (Unit: sector)
// following 8 bytes define the real-capcity (in sector) of every disk in array
VDWORD realCapacityLow; // (Unit: sector)
VDWORD realCapacityHigh; // (Unit: sector)
VDWORD stripeSize; // valid when raid is raid0, raid5 or raid01, in Kbytes
VDWORD blockSize; // valid when raid is RAID5, in Kbytes
VBOOL bNeedMigration; // the raid need migration
// only valid when raid0/raid5/matrixRaid
VBOOL bNeedInit; // the raid need initialization, only valid for RAID5
VBOOL bOptimized; // only for RAID5, this RAID5 access was optimized
VBYTE systemDisk; /* does the devices within this disk array
contain system files of current running OS ?
the probably value are:
VR_DEVICE_NOT_SYS_DISK
VR_DEVICE_MAYBE_SYS_DISK
VR_DEVICE_SYS_DISK
they are defined in this file */
VWORD raid_index;// only raid index, no meaning with stand-alone disk
VINT index; // all device index, including all raid and stand-alone disk
} vr_array_info_t;
А вот мой код (функции в библиотеке decorated, поэтому так странно выглядят в коде):
Код:
Local $pTest
$hDLL = DllOpen(@ScriptDir & "\drvInterface.dll")
;~ VINT vr_init (void);
ConsoleWrite("vr_init..." & @CRLF)
$sTest = DllCall($hDLL, "int:cdecl", "?vr_init@@YAHXZ")
;~ VINT vr_get_controller_num (VINT *pnumber);
ConsoleWrite("vr_get_controller_num..." & @CRLF)
$sTest = DllCall($hDLL, "int:cdecl", "?vr_get_controller_num@@YAHPAH@Z", "int*", "$pTest")
$iControllerNumber = $sTest[1]
ConsoleWrite("$iControllerNumber = " & $iControllerNumber & @CRLF)
;~ VINT vr_get_device_num (VINT *pnumber);
ConsoleWrite("vr_get_device_num..." & @CRLF)
$sTest = DllCall($hDLL, "int:cdecl", "?vr_get_device_num@@YAHPAH@Z", "int*", "$pTest")
$iDeviceNumber = $sTest[1]
ConsoleWrite("$iDeviceNumber = " & $iDeviceNumber & @CRLF)
;~ VINT vr_get_array_num (VINT only_raid, VINT *pnumber);
ConsoleWrite("vr_get_array_num..." & @CRLF)
$sTest = DllCall($hDLL, "int:cdecl", "?vr_get_array_num@@YAHHPAH@Z", "int", 0, "int*", "$pTest")
$iArrayNumber = $sTest[2]
ConsoleWrite("$iArrayNumber = " & $iArrayNumber & @CRLF)
$vr_array_info = DllStructCreate("ushort status;byte raidType;byte diskNum;dword capacityLow;dword capacityHigh;dword stripeSize;dword blockSize;boolean bNeedMigration;boolean bNeedInit;boolean bOptimized;byte systemDisk;byte raid_index;int index")
;~ VINT vr_get_array_info (VINT array_index, vr_array_info_t* pinfo);
ConsoleWrite("vr_get_array_info..." & @CRLF)
$sTest = DllCall($hDLL, "int:cdecl", "?vr_get_array_info@@YAHHPAU_vr_array_info@@@Z", "int", 0, "struct*", $vr_array_info)
;~ void vr_exit (void);
ConsoleWrite("vr_exit..." & @CRLF)
$sTest = DllCall($hDLL, "none", "?vr_exit@@YAXXZ")
DllClose($hDLL)
Exit
Все работает как полагается вплоть до вызова vr_get_array_info. По вызову vr_get_array_info AutoIt3.exe вызывает ошибку "память не может быть 'read'" ("Инструкция по адресу 0x7c93a514 обратилась к памяти по адресу 0x00000000"). При этом судя по консоли продолжает выполнение кода, но ошибка все равно всплывает.
Подскажите, пожалуйста, что я делаю не так?