在 Delphi XE 中,我使用 BASS audio library ,其中包含此功能:
function BASS_StreamCreateURL(url: PAnsiChar; offset: DWORD; flags: DWORD;
proc: DOWNLOADPROC; user: Pointer):HSTREAM; stdcall; external bassdll;
'url' 参数的类型是 PAnsiChar,所以在我的代码中我做了一个类型转换:
FStreamHandle := BASS_StreamCreateURL(PAnsiChar( url ) [...]
编译器在这一行发出警告:“字符串到 PAnsiChar 的可疑类型转换”。为了消除警告,我 found that推荐的方法是使用双重转换:
FStreamHandle := BASS_StreamCreateURL(PAnsiChar( AnsiString( url )) [...]
这确实消除了警告,但 BASS 函数现在返回错误代码 2(“无法打开文件”),它告诉我它收到的 URL 字符串以某种方式损坏。我看不到低音 DLL 实际接收到的内容,但在调试器中使用断点,字符串看起来不错:
var
s : PAnsiChar;
begin
s := PAnsiChar( AnsiString( url ));
此时字符串 s 看起来很好,但是当我通过它时 BASS 函数会失败。我的初始代码:PAnsiChar( url ) 与 BASS 配合得很好,但会发出警告。
那么在没有警告的情况下从 UnicodeString 到 PAnsiChar 的正确方法是什么?
最佳答案
我很惊讶
BASS_StreamCreateURL(PAnsiChar( url ) [...]
作品。如果
url
是一个 unicode 字符串,每个字符将占用两个字节。例如,如果字符串是 test
,它将读取7400 6500 7300 7400 0000 t e s t #0 (Unicode)
在内存中。请注意,字符串以空字符 (
0000
) 结尾PAnsiChar(url)
你会告诉编译器这个地址的内存应该被认为是
AnsiString
。 .但是如果你考虑上面的字节序列,你会发现在这种情况下只有“t”。事实上,作为 AnsiString
,该序列应解释为74 00 65 00 73 00 74 00 00 00 t #0 e #0 s #0 t #0 #0 #0 (Ansi)
这是字符串“t”,以空字符(
00
)结尾。PAnsiChar(AnsiString(url))
另一方面将首先将 unicode 字符串转换为 ansi 字符串,也就是说,您将获得
74 65 73 74 00 t e s t #0 (Ansi)
这是以空字符(
00
)结尾的字符串“test”。更新
我还不是通灵者,但也许 Bass 库确实需要指向
UnicodeString
的指针。作为这个函数的第一个参数?这可以解释为什么看起来很奇怪PAnsiChar(url)
作品。库可能会说“嘿,给我指向 unicode 字符串的指针,我会用它做一些手动处理”,上面的代码就是这样做的(指针只是一个指针(即,一个无符号的 32 位整数)...)。但是编译器当然会提示,因为库明确告诉编译器它需要一个
PAnsiChar
, 通常 PAnsiChar(SomeUnicodeString)
不好。如果是这种情况,当然,那么,PAnsiChar(AnsiChar(url))
不起作用。该库需要/的地址/一个 unicode 字符串,但获取/的地址/一个 ansi 字符串。
更新 2
如果我在 中的假设更新 1 是正确的,声明
function BASS_StreamCreateURL(url: PWideChar; offset: DWORD; flags: DWORD;
proc: DOWNLOADPROC; user: Pointer):HSTREAM; stdcall; external bassdll;
会让天空再次变蓝。
更新 3
从文档中:
NOTE: Delphi 2009 users should use the BASS_UNICODE flag where possible
我敢打赌,如果您在调用
BASS_StreamCreateURL
时指定此标志,问题就会消失。 !来自样本单位
Main.pas
:Channel := BASS_StreamCreateFile(FALSE, PChar(OpenDialog.FileName), 0, 0,
0 {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});
关于delphi - 在 Delphi XE 中将 UnicodeString 转换为 PAnsiChar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4543098/