D5 应用程序中调用的 D2010 DLL 中的 PChar 似乎已损坏

发布于 2024-10-31 00:21:53 字数 802 浏览 1 评论 0原文

我已经看到很多关于在 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;

I have seen many answers about calling an older DLL in D2010 (Unicode), but the problem is that I am doing just the opposite. We are writing new parts of an application (DLLs) in D2010. The parent app is written in D5 and cannot be changed out into a D2010 app for a while (maybe a couple years).

The DLL params and variables can be changed (D2010), but the parent app (D5) cannot be touched. The integer parameters seem to be fine, it is the string/PChar parameters that are not working. For example a file path string of "D:\home\special\files\" looks like '??????????????????' when I evaluate it. I changed the DLL parameters to PAnsiChar, but that didn't seem to help.

If the DLL and a host app are both compiled in the same version of Delphi, it works fine (before I added the Ansi stuff).

Any ideas?


Code sample:

In the host (D5):

fpLoadImage: procedure(sFilename: PChar); stdcall;
.
.
.
    @fpLoadImage    := GetProcAddress(hLib, 'LoadImage');

In the DLL (D2010):

procedure LoadImage(sFileName: pAnsiChar);
var
  TempStr: string;
begin
  TempStr := sFileName;
  frmViewer.ImageFileName := TempStr;
  frmViewer.PCurrentImageId(-2);
end;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

半枫 2024-11-07 00:21:53

这是因为“字符串”数据类型在您的情况下是 unicode,并且您现在正在接收 PAnsiChar。
尝试将字符串变量“TempStr”声明为 AnsiString。

It's because "string" data type is in your case unicode and you're now receiving PAnsiChar.
Try to declare your string variable "TempStr" as AnsiString.

天气好吗我好吗 2024-11-07 00:21:53

您的 DLL 应将 TempStr 声明为 AnsiString,而不是 string。当您将 sFileName 分配给它时,您正在执行从 AnsiString 到 UnicodeString 的隐式转换。打开提示和警告会告诉你这一点......:)

Your DLL should declare TempStr as AnsiString, not string. You're doing an implicit conversion from AnsiString to UnicodeString when you assign sFileName to it. Turning on hints and warnings would have advised you of this... :)

明月松间行 2024-11-07 00:21:53

正如大家所说,当您执行以下操作时,您将强制 PAnsichar 进行字符串类型转换:

TempStr := sFileName;

因为 TempStr 是一个 string。它应该是 AnsiString

如果你真的想使用strings而不是ansistrings,你应该这样做:

TempStr := string(AnsiString(sFileName));这个可能适合您(未经测试)。

只是为了明确一点:

在 Delphi 2010 中:

  • Pchar 应转换为 string (unicode)
  • PAnsiChar 应转换为 AnsiString< /代码> (ansi)。

查看此链接,了解有关 Unicode 转换的一系列提示:

Unicode 世界中的 Delphi 第三部分:统一代码< /a>

您还可以检查 TEncoding 类:T编码

As everyone said, you are forcing a PAnsichar to string typecast when you do:

TempStr := sFileName;

because TempStr is a string. It should be AnsiString.

If you really wanna work with strings instead of ansistrings you should do:

TempStr := string(AnsiString(sFileName)); This may work for you (untested).

Just to make it clear:

In Delphi 2010:

  • Pchar should be cast to string (unicode)
  • PAnsiChar should be cast to AnsiString (ansi).

Check out this link for a series of tips about Unicode conversion:

Delphi in a Unicode World Part III: Unicodifying Your Code

You may also check the TEncoding class: TEncoding

黑色毁心梦 2024-11-07 00:21:53

我没有发现您发布的代码有任何问题。

当然,就像许多人已经提到的那样,您可以在线进行从 pAnsiChar 到 AnsiString 到 String 的隐式转换

TempStr := sFileName;

,但这不会损坏字符串。

您是否尝试在分配后立即使用 ShowMessage(TempStr) ? (只是为了确保不是delphi的调试器在调试时无法正确评估字符串)。或者甚至在函数的开头放置一个断点,并评估(在调试中)Pchar(sFileName)PAnsiChar(sFileName) (以查看指针是否已 我要

检查的另一件事是在调试时加载了 DLL 的哪个版本。也许您调试时加载的 DLL 不是最新的“ansi”更改。我不认为Delphi保证主机应用程序将加载的DLL将是刚刚编译的DLL,它将是主机应用程序在Windows DLL搜索路径上找到的第一个DLL(我对此可能是错误的)尽管)。

哦...最后但并非最不重要的一点是,确保您没有意外删除 DLL 中的“stdcall”...嗯...实际上,您应该先这样做! :P

目前我能想到的就是这些了...

I don't see anything wrong with the code you posted.

Of course, like many have already mentionned, you do an implicit conversion from pAnsiChar to AnsiString to String on line

TempStr := sFileName;

But that doesn't corrupt the string.

Did you try to use ShowMessage(TempStr) right after it is assigned? (Just to make sure it's not delphi's debugger that doesn't evaluate the string properly in debug). Or even put a breakpoint right at the beginning of the function and and evaluate (in debug) both Pchar(sFileName) and PAnsiChar(sFileName) (To see if the pointer has any valid data to start with)

Another thing I'd check is exactly which version of the DLL was loaded at the time it was debugged. Maybe the DLL that was loaded when you debugged wasn't the latest with your "ansi" change. I don't think Delphi guarantee the DLL that will be loaded by the host application will be the one that was just compiled, it will be the first one the host application find on the windows' DLL search path (I might be wrong about this though).

Oh... and last but not the least, make sure you didn't delete the "stdcall" in the DLL by accident... hmmm... Actually, you should do that first! :P

That's all I can think of right now...

暗地喜欢 2024-11-07 00:21:53

谢谢托德雷吉。我忘了放StdCall;最后它弄乱了 PChar 参数。吸引人的总是简单的事情。

该过程使用字符串而不是 ansistring 的原因是,我在排除故障时更改了过程,并且在剪切并粘贴代码之前忘记将其放回去。对此感到抱歉。

感谢大家的帮助。我只需要编写代码,以便它现在可以在 ansi 和 unicode 中工作。我想我在转换之前找到了一个调用来评估系统

Tom

Thanks TOndrej. I forgot to put StdCall; at the end and it messed up the PChar parameters. It is always the simple things that get a person.

The reason that the procedure had string instead of ansistring, is that I was changing the procedure while I was troubleshooting and forgot to put it back before I cut and pasted the code in. Sorry about that.

Thanks for everyone's help. I just need to write the code so that it will work in ansi and unicode now. I think I found a call somewhere to evaluate the system before the conversion

Tom

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文