2016-10-24 57 views
1

我的第一个问题在这里。如果我做错了什么,请给我一个提示。如何通过Delphi包装器调用C++函数

我的问题:我必须通过Delphi包装器(VCL)调用C++函数。 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); 

这是我的问题,如何处理德尔福的指针。我认为这是德尔福的正确呼吁:

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; 
+0

你必须告诉我们'FoxBurnerSDKCore.ReadFileContents'的定义 – AmigoJack

+0

嗨AmigoJack,我已经添加了两个定义到问题中。 – IFDev

+0

这里没有足够的信息。因此,投票表决并投票。请提供关于如何调用该函数的完整说明,并对代码进行格式化以便于阅读。 –

回答

0

应该这样定义的:

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); 
+0

@buffer [0]导致编译器错误。 – IFDev

+0

定义“a”。还编辑了我的答案完整的调用示例,所以你不会摆弄我们不知道的类型。 – AmigoJack

+0

我得到了一个DLL的版本,其中的一切都在这个函数中进行了评论。所以它只是返回一个0.该函数将导致崩溃。那么C++函数的声明有可能是错误的? – IFDev

0

如果FoxBurnerSDKCore定义正确的C++函数,然后照顾约buffer说法。对于动态数组Bytes必须使用Bytes[0]外部Delphi函数的参数

(以避免C++函数调用与“指向指针”参数值,因为达因。阵列TB的内部已经被指针阵列数据)

+0

我已经在问题中添加了定义。我也尝试Bytes [0]相同的结果。 – IFDev

+0

您使用的是什么Delphi版本?如果Unicode一个,检查'AnsiString'为'FilePath' – MBo

+0

我使用Rad Studio 10.1 – IFDev

-1

我很抱歉,这是从C++切换到Delphi的人的问题。经过几个小时的调试后,我发现函数及其声明没有初始化。 我现在还说:

ReadFileContents:=GetProcAddress(h,'ReadFileContents'); ok:=ok and (@ReadFileContents<>nil); 

在包装的功能列表,现在一切都运行完美。感谢所有给我答案的人。所有这些答案对于一个beiginner来说都是完美的,并且学到了一些东西再次,非常感谢。

+0

请注意,如果您向我们展示了MCVE,可能会在五分钟内解决此问题http://stackoverflow.com/help/mcve – MBo

+0

这不是您询问的问题的答案。我们不可能猜到这一点。学习创建一个MCVE,当你问这样的问题。 –