Мой первый вопрос здесь. Пожалуйста, дайте мне подсказку, если я сделаю что-то не так.
Мой вопрос: я должен вызывать функцию c ++ через оболочку Delphi (VCL). Оболочка delphi выглядит так:
function TFoxBurnerSDK.ReadFileContents(FilePath: string; Offset: int64; var Buffer; Length: integer; var ActualLength: integer): boolean;
begin
CheckActive;
if FSessionHandle=nil then begin
FLastError:=BS_SDK_ERROR_BAD_REQUEST;
Result:=false;
Exit;
end;
Result:=DLLResult(FoxBurnerSDKCore.ReadFileContents(FSessionHandle,
PFoxSDKChar(FoxSDKString(FilePath)), Offset, @buffer, Length, @ActualLength));
end
Как вызвать эту функцию из кода Delphi. Имеется в виду, что var / параметр мне нужно будет отправить в функцию? Похоже, что буфер и ActualLength являются указателями в C ++
int32 BS_CALL ReadFileContents( HSESSION hSession, const TCHAR* lpszFilePath, int64 nOffset, void* pBuffer, int32 nBufferSize, int32* pRead );
И это проблема для меня, как обращаться с указателями в Delphi. Я думал, что это правильный вызов в Delphi:
procedure TForm1.Button1Click(Sender: TObject);
var Bytes: TBytes;
iRead : integer;
begin
SetLength(Bytes, 2352*27);
iRead:=0;
Burner.ReadFileContents('\autorun.inf', 0, Bytes, 2352*27, iRead);
end;
Но это приведет к памяти. Если я вызываю функцию из образца C ++, она работает хорошо. Просто здесь, в Дельфи, случается ожидание. Поэтому я думаю, что сделал что-то не так.
Я надеюсь, что дал всю необходимую информацию, чтобы получить ответ. Если нет, пожалуйста, дайте мне знать, что я скучаю. Спасибо.
Добавленная информация: Определение:
ReadFileContents : function (Session: HSESSION; FilePath: PFoxSDKChar; Offset: int64; Buffer: pointer; BufferSize: integer; Read: pinteger): integer; stdcall;
function ReadFileContents(FilePath: string; Offset: int64; var Buffer; Length: integer; var ActualLength: integer): boolean;
Это должно быть определено так:
ReadFileContents: function
( Session: HSESSION // HSESSION
; FilePath: PChar // TCHAR*
; Offset: Int64 // int64
; Buffer: Pointer // void*
; BufferSize: Integer // int32
; Read: PInteger // int32*
): Integer; // int32
cdecl; // C++, don't know why you use stdcall
И звонок должен быть
var
iResult, iLength, iRead: Integer;
sFilePath: String;
iOffset: Int64;
aBuf: Array of Byte;
begin
iLength:= 5;
SetLength( aBuf, iLength );
iResult:= ReadFileContents( FSessionHandle, PChar(sFilePath), iOffset, @aBuf[0], iLength, @iRead );
Если FoxBurnerSDKCore
правильно определяет функцию C ++, затем позаботьтесь о buffer
аргумент. Для динамического массива Bytes
ты должен использовать Bytes[0]
в качестве аргумента внешней функции Delphi
(чтобы избежать вызова функции c ++ со значением аргумента ‘указатель на указатель’, потому что dyn. массив TBytes внутри уже является указателем на данные массива)
Извините, это проблема людей, которые переходят с C ++ на Delphi. После нескольких часов отладки я обнаружил, что функция и ее объявление не были инициализированы.
Я сейчас добавил:
ReadFileContents:=GetProcAddress(h,'ReadFileContents'); ok:=ok and (@ReadFileContents<>nil);
к списку функций в обертке и теперь все работает отлично. Спасибо всем, кто дал мне ответ. Все эти ответы были идеальны для начинающих и чему-то научиться. Еще раз большое спасибо.