我已经看到很多关于在D2010(Unicode)中调用旧DLL的答案,但问题是我正在做相反的事情。我们正在D2010中编写应用程序的新部分(DLL)。父应用程序是用D5编写的,不能在一段时间内(可能是几年)更改为D2010应用程序。
可以更改DLL参数和变量(D2010),但无法触及父应用程序(D5)。整数参数似乎很好,它是不起作用的字符串/ PChar参数。例如,文件路径字符串“D:\ home \ special \ files \”看起来像'??????????????????当我评价它。我将DLL参数更改为PAnsiChar,但这似乎没有帮助。
如果DLL和主机应用程序都是在相同版本的Delphi中编译的,那么它的工作正常(在我添加Ansi之前)。
有什么想法吗?
代码示例:
在主持人(D5)中:
fpLoadImage: procedure(sFilename: PChar); stdcall;
.
.
.
@fpLoadImage := GetProcAddress(hLib, 'LoadImage');
在DLL(D2010)中:
procedure LoadImage(sFileName: pAnsiChar);
var
TempStr: string;
begin
TempStr := sFileName;
frmViewer.ImageFileName := TempStr;
frmViewer.PCurrentImageId(-2);
end;
答案 0 :(得分:3)
这是因为“string”数据类型在您的情况下是unicode,而您现在正在接收PAnsiChar。 尝试将您的字符串变量“TempStr”声明为AnsiString。
答案 1 :(得分:2)
您的DLL应将TempStr
声明为AnsiString
,而不是string
。当您为其分配sFileName
时,您正在进行从AnsiString到UnicodeString的隐式转换。打开提示和警告会告诉你这个......:)
答案 2 :(得分:0)
正如大家所说的那样,当你这样做时,你正在强迫PAnsichar进行类型转换:
TempStr := sFileName;
因为TempStr是string
。它应该是AnsiString
。
如果你真的想与strings
而不是ansistrings
合作,你应该这样做:
TempStr := string(AnsiString(sFileName));
可能适合您(未经测试)。
只是说清楚:
在Delphi 2010中:
Pchar
应该投放到string
(unicode)PAnsiChar
应该投放到AnsiString
(ansi)。查看此链接以获取有关Unicode转换的一系列提示:
Delphi in a Unicode World Part III: Unicodifying Your Code
您还可以查看TEncoding
课程:TEncoding
答案 3 :(得分:0)
我发布的代码没有任何问题。
当然,就像许多人已经提过的那样,你可以从pAnsiChar到AnsiString到String的隐式转换
TempStr := sFileName;
但这不会破坏字符串。
您是否在分配后立即尝试使用ShowMessage(TempStr)
? (只是为了确保它不是delphi的调试器,不能在调试中正确评估字符串)。或者甚至在函数的开头放置一个断点,并评估(在调试中)Pchar(sFileName)
和PAnsiChar(sFileName)
(看看指针是否有任何有效数据开始)
我要检查的另一件事是在调试时加载了哪个版本的DLL。也许你调试时加载的DLL不是你的“ansi”更改的最新版本。我不认为Delphi保证将由主机应用程序加载的DLL将是刚编译的那个,它将是主机应用程序在windows的DLL搜索路径上找到的第一个(我可能错了)虽然)。
哦......最后但并非最不重要,请确保你没有意外删除DLL中的“stdcall”......嗯......实际上,你应该先这样做! :P
这就是我现在所能想到的......
答案 4 :(得分:0)
感谢TOndrej。我忘了把StdCall;最后,它搞砸了PChar参数。获得一个人总是很简单的事情。
该过程具有字符串而不是ansistring的原因是我在进行故障排除时更改了该过程,并且在我剪切并粘贴代码之前忘记将其放回去。抱歉。
感谢大家的帮助。我只需要编写代码,以便它现在可以在ansi和unicode中使用。我想在转换之前我在某个地方找到了一个评估系统的电话
汤姆