Я поражен, что
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)
- строка «test», заканчивающаяся нулевым символом (00
).
Обновление
Я не экстрасенс (пока), но, может быть, библиотеке Басов действительно требуется указатель на UnicodeString
в качестве первого аргумента этой функции? Это объяснило бы, почему казалось бы странным
PAnsiChar(url)
работает. Библиотека может сказать: «Эй, просто дай мне указатель на строку Unicode, и я сделаю некоторую ручную обработку с ней», и приведенный выше код делает именно это (указатель - это просто указатель (то есть 32-разрядный без знака целое число) ...). Но компилятор будет жаловаться, конечно, потому что простота библиотеки сказала компилятору, что для нее потребуется PAnsiChar
, а обычно PAnsiChar(SomeUnicodeString)
- это плохо. Если это так, то, конечно,
PAnsiChar(AnsiChar(url))
не работает. Библиотека ожидает / адрес / строки Юникода, но получает / адрес / строки 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_StreamCreateURL
!
Из единицы измерения Main.pas
:
Channel := BASS_StreamCreateFile(FALSE, PChar(OpenDialog.FileName), 0, 0,
0 {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});