我正在使用Delphi XE6开发,如果有所关联。
我正在编写一个DLL,该DLL将从谷歌地图的方向API获取响应,并解析结果JSON以确定行程的总距离。
GetJSONString_OrDie
按预期工作。它获取一个URL并试图从谷歌获取响应。 如果成功,则返回谷歌返回的JSON字符串。
ExtractDistancesFromTrip_OrDie
应接收一个JSON字符串,并解析它以获取每个路段的总距离,并将这些距离保存在双精度数组中。
SumTripDistances
接收一个双精度数组,对数组进行求和,并返回总数。
有趣的是,如果我将这些函数从DLL中取出并放入项目中直接调用,那么它按预期工作。 只有当它们被放入DLL时,事情似乎出了问题。 如上所述,GetJSONString_OrDie
按预期工作并返回JSON字符串-但是当通过DLL的ExtractDistancesForTrip
进行步进时,传递的PChar字符串是''
。 为什么会这样?
unit Unit1;
interface
uses
IdHTTP,
IdSSLOpenSSL,
System.SysUtils,
System.JSON;
type
arrayOfDouble = array of double;
function GetJSONString_OrDie(url : Pchar) : Pchar;
function ExtractDistancesForTrip_OrDie(JSONstring: Pchar) : arrayOfDouble;
function SumTripDistances(tripDistancesArray: arrayOfDouble) : double;
implementation
{ Attempts to get JSON back from Google's Directions API }
function GetJSONString_OrDie(url : Pchar) : PChar;
var
lHTTP: TIdHTTP;
SSL: TIdSSLIOHandlerSocketOpenSSL;
begin
{Sets up SSL}
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
{Creates an HTTP request}
lHTTP := TIdHTTP.Create(nil);
{Sets the HTTP request to use SSL}
lHTTP.IOHandler := SSL;
try
{Attempts to get JSON back from Google's Directions API}
Result := PWideChar(lHTTP.Get(url));
finally
{Frees up the HTTP object}
lHTTP.Free;
{Frees up the SSL object}
SSL.Free;
end;
end;
{ Extracts the distances from the JSON string }
function ExtractDistancesForTrip_OrDie(JSONstring: Pchar) : arrayOfDouble;
var
jsonObject: TJSONObject;
jsonArray: TJSONArray;
numberOfLegs: integer;
I: integer;
begin
//raise Exception.Create('ExtractDistancesForTrip_OrDie:array of double has not yet been '+
// 'implemented.');
jsonObject:= nil;
jsonArray:= nil;
try
{ Extract the number of legs in the trip }
jsonObject:= TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(JSONstring), 0) as TJSONObject;
jsonObject:= (jsonObject.Pairs[0].JsonValue as TJSONArray).Items[0] as TJSONObject;
jsonArray:= jsonObject.Pairs[2].JSONValue as TJSONArray;
numberOfLegs:= jsonArray.Count;
{Resize the Resuls arrayOfDouble}
SetLength(Result, numberOfLegs);
{Loop through the json and set the result of the distance of the leg}
{Distance is in km}
for I := 0 to numberOfLegs-1 do
begin
Result[I]:= StrToFloat((((jsonArray.Items[I] as TJSONObject).Pairs[0].JsonValue as TJSONObject).Pairs[1]).JsonValue.Value);
end;
finally
jsonObject.Free;
jsonArray.Free;
end;
end;
function SumTripDistances(tripDistancesArray: arrayOfDouble) : double;
var
I: integer;
begin
//raise Exception.Create('GetDistanceBetweenPoints_OrDie:double has not yet been ' +
// 'implemented.');
Result:= 0;
{Loop through the tripDistancesArray, and add up all the values.}
for I := Low(tripDistancesArray) to High(tripDistancesArray) do
Result := Result + tripDistancesArray[I];
end;
end.
以下是函数调用的方法:
方法如下:
program Project3;
{$APPTYPE CONSOLE}
{$R *.res}
uses
ShareMem,
IdHTTP,
IdSSLOpenSSL,
System.SysUtils,
System.JSON,
System.Classes;
type
arrayOfDouble = array of double;
testRecord = record
testString : string;
testInt : integer;
end;
function GetJSONString_OrDie(url : Pchar) : PWideChar; stdcall; external 'NMBSGoogleMaps.dll';
function ExtractDistancesForTrip_OrDie(JSONstring: pchar) : arrayOfDouble; stdcall; external 'NMBSGoogleMaps.dll';
function SumTripDistances(tripDistancesArray: arrayOfDouble) : double; stdcall; external 'NMBSGoogleMaps.dll';
var
jsonReturnString: string;
jsonReturnString2: Pchar;
doubles: arrayOfDouble;
totalJourney: double;
uri:Pchar;
a : testRecord;
begin
try
uri:= 'https://maps.googleapis.com/maps/api/directions/json?origin=Boston,MA&destination=Concord,MA&waypoints=Charlestown,MA|Lexington,MA&key=GETYOUROWNKEY';
{ TODO -oUser -cConsole Main : Insert code here }
jsonReturnString:= GetJSONString_OrDie(uri); //On step-through, uri is fine.
jsonReturnString2:= stralloc(length(jsonreturnstring)+1);
strpcopy(jsonreturnstring2, jsonreturnstring);
jsonreturnstring2 := 'RANDOMJUNK';
doubles:= ExtractDistancesForTrip_OrDie(jsonReturnString2); //On step-through, jsonReturnString2 is seen as '', rather than 'RANDOMJUNK'
totalJourney:= SumTripDistances(doubles);
WriteLn('The total journey was: ');
WriteLn(totalJourney);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
readln;
end.
当第一个函数被调用时,
GetJSONString_OrDie
,uri被传入并且在查看或打印出来时是正确的。
然而,在创建随机字符串并将其传递给ExtractDistancesForTrip_OrDie
之后,该函数仅看到''
。如果我更改ExtractDistancesForTrip_OrDie
以接受整数,记录或任何内容-它会看到垃圾或随机数据。无论是否通过引用或值传递都没有关系。