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 canno开发者_运维百科t 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;
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.
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... :)
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 tostring
(unicode)PAnsiChar
should be cast toAnsiString
(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
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...
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
精彩评论