如何将大型字符串从delphi dll传递到php扩展
我已经在VisualStudioExpress中为Windows7的PHP7.2NTS编写了一个php扩展(全部为64位)。我用它来访问第三方。用C++编写的DLL,工作正常。 现在我想让它访问我在DelphiXe6中编写的.dll。.dll中的函数以PAnsiChar的形式返回字符串。它实际上是一个base64编码的jpeg图像,因此可能相当大。我选择将其作为base64编码字符串发送,因为我看不到任何将图像或字节数组从扩展传递回PHP的方法 我的Delphi代码是:如何将大型字符串从delphi dll传递到php扩展,php,delphi,Php,Delphi,我已经在VisualStudioExpress中为Windows7的PHP7.2NTS编写了一个php扩展(全部为64位)。我用它来访问第三方。用C++编写的DLL,工作正常。 现在我想让它访问我在DelphiXe6中编写的.dll。.dll中的函数以PAnsiChar的形式返回字符串。它实际上是一个base64编码的jpeg图像,因此可能相当大。我选择将其作为base64编码字符串发送,因为我看不到任何将图像或字节数组从扩展传递回PHP的方法 我的Delphi代码是: function dem
function dem_get_map_img(imgdata: PAnsiChar): int32; stdcall;
var
base64str: ansistring;
begin
base64str := 'test return value'; // the actual image data will go here
imgdata := PAnsiChar(base64str);
Result := 27; // some meaningful value will be used later
end;
我的PHP扩展代码是:
PHP_FUNCTION(dem_get_map_img)
{
hGetProcIDDelphiDLL = LoadLibrary(_T("delphiDLL.dll"));
if (!hGetProcIDDelphiDLL) RETURN_STRING("dll not loaded");
int rc;
char imgdata[AS_MAXCH];
if (ZEND_NUM_ARGS() != 0) RETURN_STRING("wrong param count loaded");
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE(hGetProcIDDelphiDLL), "dem_get_map_img");
if (!lpfnGetProcessID) RETURN_STRING("function not found");
typedef int32(__stdcall * pICFUNC)(char *imgdata);
pICFUNC dem_get_map_img;
dem_get_map_img = pICFUNC(lpfnGetProcessID);
rc = dem_get_map_img(imgdata);
FreeLibrary(hGetProcIDDelphiDLL);
array_init(return_value);
add_assoc_long(return_value, "retflag", rc);
add_assoc_string(return_value, "imgdata", imgdata);
}
PHP_FUNCTION(dem_get_map_img)
{
hGetProcIDDelphiDLL = LoadLibrary(_T("delphiDLL.dll"));
if (!hGetProcIDDelphiDLL) RETURN_STRING("not loaded");
long rc, imgsize;
char * imgdata;
if (ZEND_NUM_ARGS() != 0) RETURN_STRING("wrong param count loaded");
FARPROC lpfnGetPrepID = GetProcAddress(HMODULE(hGetProcIDDelphiDLL), "dem_prepare_map_img");
if (!lpfnGetPrepID) RETURN_STRING("prepare function not found");
typedef int32(__stdcall * pICprep)(long wid, long hei);
pICprep dem_prepare_map_img;
dem_prepare_map_img = pICprep(lpfnGetPrepID);
imgsize = dem_prepare_map_img(900, 450);
imgdata = (char*)malloc(imgsize);
FARPROC lpfnGetGetID = GetProcAddress(HMODULE(hGetProcIDDelphiDLL), "dem_get_map_img");
if (!lpfnGetGetID) RETURN_STRING("get function not found");
typedef int32(__stdcall * pICget)(char *imgdata);
pICget dem_get_map_img;
dem_get_map_img = pICget(lpfnGetGetID);
rc = dem_get_map_img(imgdata);
FreeLibrary(hGetProcIDDelphiDLL);
array_init(return_value);
add_assoc_long(return_value, "retflag", rc);
add_assoc_long(return_value, "imgsize", imgsize);
add_assoc_string(return_value, "imgdata", imgdata);
free(imgdata);
}
我的PHP代码是:
$outval = dem_get_map_img();
var_dump($outval);
这给了我:
array(2) {
["retflag"]=>
int(27)
["imgdata"]=>
string(4) "�$�"
}
不是我所希望的
首先,我注意到AS_MAXCH显然只允许我使用255个字符,这将是一个问题(帮助?),但到目前为止不应该是问题
我已经阅读了各种类似的问题,并假设释放内存可能是问题所在,但到目前为止,我还不知道该怎么办
我见过有人推荐使用CoTaskMemAlloc,但我在Delphi中如何做到这一点
我真正需要做的是将一个Jpeg图像从我的Delphi dll传递到PHP扩展,并传递到我的PHP代码中,因此如果有更好的方法,我愿意接受建议。我对C/C++和PHP扩展的了解非常有限(你已经知道了,不是吗)
任何帮助都将不胜感激
更新:
你能有多蠢(…我能有多蠢)
我刚刚意识到我在Delphi函数中做错了什么
修订德尔福函数:
function dem_get_map_img(imgdata: PAnsiChar): int32; stdcall;
var
base64str: ansistring;
begin
base64str:= 'test return value';
StrPCopy(imgdata, base64str);
Result := 27;
end;
填充平底锅,不要创建新的
我仍然很好奇,是否有人有更好的建议将图像或大块数据传递给PHP
更新2:
嗯,非常感谢大卫·赫弗南为我指明了正确的方向,我想我已经做到了
我拆分了Delphi函数,现在有一个函数准备字符串并返回大小
Result := length(MapImage) * sizeof(ansichar) + 1;
和另一个一样返回实际字符串数据
现在我调用第一个函数来准备数据,并在调用第二个函数之前使用返回的数据大小来分配内存
我的新扩展代码是:
PHP_FUNCTION(dem_get_map_img)
{
hGetProcIDDelphiDLL = LoadLibrary(_T("delphiDLL.dll"));
if (!hGetProcIDDelphiDLL) RETURN_STRING("dll not loaded");
int rc;
char imgdata[AS_MAXCH];
if (ZEND_NUM_ARGS() != 0) RETURN_STRING("wrong param count loaded");
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE(hGetProcIDDelphiDLL), "dem_get_map_img");
if (!lpfnGetProcessID) RETURN_STRING("function not found");
typedef int32(__stdcall * pICFUNC)(char *imgdata);
pICFUNC dem_get_map_img;
dem_get_map_img = pICFUNC(lpfnGetProcessID);
rc = dem_get_map_img(imgdata);
FreeLibrary(hGetProcIDDelphiDLL);
array_init(return_value);
add_assoc_long(return_value, "retflag", rc);
add_assoc_string(return_value, "imgdata", imgdata);
}
PHP_FUNCTION(dem_get_map_img)
{
hGetProcIDDelphiDLL = LoadLibrary(_T("delphiDLL.dll"));
if (!hGetProcIDDelphiDLL) RETURN_STRING("not loaded");
long rc, imgsize;
char * imgdata;
if (ZEND_NUM_ARGS() != 0) RETURN_STRING("wrong param count loaded");
FARPROC lpfnGetPrepID = GetProcAddress(HMODULE(hGetProcIDDelphiDLL), "dem_prepare_map_img");
if (!lpfnGetPrepID) RETURN_STRING("prepare function not found");
typedef int32(__stdcall * pICprep)(long wid, long hei);
pICprep dem_prepare_map_img;
dem_prepare_map_img = pICprep(lpfnGetPrepID);
imgsize = dem_prepare_map_img(900, 450);
imgdata = (char*)malloc(imgsize);
FARPROC lpfnGetGetID = GetProcAddress(HMODULE(hGetProcIDDelphiDLL), "dem_get_map_img");
if (!lpfnGetGetID) RETURN_STRING("get function not found");
typedef int32(__stdcall * pICget)(char *imgdata);
pICget dem_get_map_img;
dem_get_map_img = pICget(lpfnGetGetID);
rc = dem_get_map_img(imgdata);
FreeLibrary(hGetProcIDDelphiDLL);
array_init(return_value);
add_assoc_long(return_value, "retflag", rc);
add_assoc_long(return_value, "imgsize", imgsize);
add_assoc_string(return_value, "imgdata", imgdata);
free(imgdata);
}
我的网页上有一张漂亮的地图
我现在唯一真正关心的是自由(imgdata)正在实现。据我所知,扩展函数只在函数末尾返回return_值,而不是像return_STRING()那样立即返回 如果你的知识像你说的那样有限,那么他的问题在这里是无法解决的。你还没有解决问题的技能,我们也不能帮你。是你学习的时候了。我不确定,但我想到的第一件事是类型不兼容。“也许你应该试试PWideChar或其他什么?”亚历克斯猜测不太可能有帮助。你的猜测完全错误。哦,在
dem\u get\u map\u img(imgdata:PAnsiChar)
@AlexSlipknot:var中没有var
。在这里随意抓救命稻草是没有帮助的。