Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi-XE中UnicodeString到PAnsiChar的转换_Delphi_Pointers_Delphi Xe_Unicode String_Ansistring - Fatal编程技术网

Delphi-XE中UnicodeString到PAnsiChar的转换

Delphi-XE中UnicodeString到PAnsiChar的转换,delphi,pointers,delphi-xe,unicode-string,ansistring,Delphi,Pointers,Delphi Xe,Unicode String,Ansistring,在Delphi XE中,我使用的是,它包含以下函数: function BASS_StreamCreateURL(url: PAnsiChar; offset: DWORD; flags: DWORD; proc: DOWNLOADPROC; user: Pointer):HSTREAM; stdcall; external bassdll; “url”参数的类型为PAnsiChar,因此在我的代码中,我执行了一个强制转换: FStreamHandle := BASS_StreamC

在Delphi XE中,我使用的是,它包含以下函数:

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”。在试图消除警告时,我建议使用双重强制转换:

FStreamHandle := BASS_StreamCreateURL(PAnsiChar( AnsiString( url )) [...]
这确实消除了警告,但是BASS函数现在返回错误代码2(“无法打开文件”),它告诉我它接收到的URL字符串不知何故被破坏了。我看不到bass DLL实际接收到什么,但在调试器中使用断点,字符串看起来不错:

var
  s : PAnsiChar;
begin
  s := PAnsiChar( AnsiString( url ));
此时字符串s看起来很好,但当我传递它时,低音功能失败。我的初始代码:PAnsiChar(url)与BASS配合得很好,但会发出警告

那么,在没有任何警告的情况下,从独角兽毁灭到潘斯卡尔的正确方式是什么呢?

我很惊讶

BASS_StreamCreateURL(PAnsiChar( url ) [...]
工作。如果
url
是unicode字符串,则每个字符将占用两个字节。例如,如果字符串是
test
,它将读取

7400 6500 7300 7400 0000                t e s t #0                     (Unicode)
在记忆中。请注意,执行此操作时,字符串以空字符(
0000
)结尾

PAnsiChar(url)
您将告诉编译器,此地址的内存应被视为一个
AnsiString
。但是如果你考虑上面的字节序列,在这种情况下你只会发现“t”。事实上,作为一个
应答
,序列应该被解释为

74 00 65 00 73 00 74 00 00 00           t #0 e #0 s #0 t #0 #0 #0      (Ansi)
这是字符串“t”,以空字符(
00
)结尾

另一方面,将首先将unicode字符串转换为ansi字符串,也就是说,您将获得

74 65 73 74 00                           t e s t #0                    (Ansi)
这是以空字符(
00
)结尾的字符串“test”

更新 我还不是通灵者,但也许Bass库确实需要一个指向UnicodeString的指针作为该函数的第一个参数?这就解释了为什么这看起来很奇怪

PAnsiChar(url)
工作。库可能会说“嘿,给我一个指向unicode字符串的指针,我会用它进行一些手动处理”,上面的代码就是这么做的(指针就是一个指针(即,一个无符号的32位整数)…)。但是编译器当然会抱怨,因为库明确地告诉编译器它需要一个
PAnsiChar
,通常
PAnsiChar(destring)
是坏的。当然,如果是这样的话

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 从文件中:

注意:Delphi 2009用户应尽可能使用BASS_UNICODE标志

我敢打赌,如果在调用
BASS\u StreamCreateURL
时指定此标志,问题就会消失

从样本单元
Main.pas

Channel := BASS_StreamCreateFile(FALSE, PChar(OpenDialog.FileName), 0, 0,
    0 {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});

根据我的经验,以下代码片段非常有用。
{$IFDEF UNICODE}
BASS_UNICODE{$ENDIF}

我完全同意你的分析。然而,“Susticiuos”类型转换是有效的,而应该正确的类型转换会产生BASS的错误。Delphi XE和2009中的行为相同。(BASS附带的一个演示也使用了从string到PAnsiChar的简单转换。)更新3:BASS_UNICODE标志确实出现在我的代码中。你之前的预感可能是对的。由于指定了标志,因此BASS需要PWideChar,即使声明中另有说明。非常感谢,安德烈亚斯!我刚刚使用了AnsiString AnsiString:myURL;myURL:='http://...'BASS_StreamCreateURL(PAnsiChar(myURL),0,[…],并在Delphi XE2上工作
Channel := BASS_StreamCreateFile(FALSE, PChar(OpenDialog.FileName), 0, 0,
    0 {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});