Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   PWideChar und PAnsiChar (https://www.delphipraxis.net/132741-pwidechar-und-pansichar.html)

EWeiss 18. Apr 2009 16:53


PWideChar und PAnsiChar
 
Hab leider wieder ein kleines problem
Meine Function erwartet als Rückgabe PAnsiChar

Die Dll welche ich einlese übergibt PWideChar
Das ergebinis ist 'Visual Demo PlugIn'

Übergebe ich es aber an meine Funktion bleibt nur noch ein 'V' übrig
Wie kann ich das korrigieren ?

Kann es nicht ändern da die anderen Plugins alle ein PAnsiChar erwarten.

hier noch was code..

Delphi-Quellcode:
function BASSVIS_GetPluginName(Param: PBASSVIS_PARAM): PAnsiChar; stdcall;
begin
  BASSVISKIND_AIMP2: Result := PAnsiChar(BASS_AIMP2VIS_GetName(Param^.VisHandle))
end;

function BASS_AIMP2VIS_GetName(handle: HVIS): PWideChar; stdcall;
begin
  Result := VisInfo^.VisPointer.PluginInfo;
end;

  IAIMP2VisualPlugin = interface
    function AuthorName: PWideChar; stdcall;
    function PluginName: PWideChar; stdcall;
    function PluginInfo: PWideChar; stdcall;

gruss Emil

Bernhard Geyer 18. Apr 2009 16:56

Re: PWideChar und PAnsiChar
 
Du könntest einen harten Cast nach PWidechar durchführen und dann dir den String geben lassen.

Sinnvoller ist es aber eine Unicode-Interface neben den Ansi-Interface zu definieren.

EWeiss 18. Apr 2009 17:01

Re: PWideChar und PAnsiChar
 
Zitat:

Zitat von Bernhard Geyer
Du könntest einen harten Cast nach PWidechar durchführen und dann dir den String geben lassen.

Sinnvoller ist es aber eine Unicode-Interface neben den Ansi-Interface zu definieren.

Hab noch was code addiert ..
Schau bitte nochmal ;)

Ich brauche als rückgabe PAnsiChar aber dann wird nur noch das 'V' ausgegeben.
Obwohl innerhalb der Funktion BASS_AIMP2VIS_GetName bei Result der richtige Name noch steht.

In BASSVIS_GetPluginName ist es dann nur noch 'V'

gruss Emil

lbccaleb 18. Apr 2009 17:03

Re: PWideChar und PAnsiChar
 
Das sollte eigentlich mit


Delphi-Quellcode:
var

  test: PansiChar;
  pwchar: PWideChar;
begin
  test := 'Hallo';
  pwchar := StringToOleStr(test);
end;
funktionieren!

EWeiss 18. Apr 2009 17:19

Re: PWideChar und PAnsiChar
 
Zitat:

Zitat von lbccaleb
Das sollte eigentlich mit


Delphi-Quellcode:
var

  test: PansiChar;
  pwchar: PWideChar;
begin
  test := 'Hallo';
  pwchar := StringToOleStr(test);
end;
funktionieren!

Das funktioniert nicht.
Delphi-Quellcode:
VisPointer     : function: IAIMP2VisualPlugin; stdcall;
function PluginName: PWideChar; stdcall;
Setze ich die Funktion jetzt auf PAnsiChar
Delphi-Quellcode:
function BASS_AIMP2VIS_GetModuleName(handle: HVIS): PAnsiChar; stdcall;
Result := PAnsiChar(VisInfo^.VisPointer.PluginName);
bekomme ich nur ein 'V'

so!
Delphi-Quellcode:
Result := StringToOleStr(VisInfo^.VisPointer.PluginName);
dann meckert er immer noch WideChar und Char..

gruss Emil

himitsu 18. Apr 2009 17:20

Re: PWideChar und PAnsiChar
 
ein harter Cast ändert nur den Zeigertyp, aber nicht die enthaltenen Daten.

innerhalb einer Funktion könnte man auch sowas nutzen,
Delphi-Quellcode:
pwchar := PAnsiChar(AnsiString(test));
aber sobald man die Funktion/Prozedur verläßt, benötigt man einen Zwischenspeicher für die Ansi-Daten, damit diese nicht schon freigegeben sind, wenn sie dann außerhalb verwendet werden sollen.

Delphi-Quellcode:
var // globale TempVariable (aber global ist auch böse und hat Nachteile)
  testTemp: AnsiString;
 
var
  test: PWideChar oder WideString;
begin
  test := 'Hallo';

  ...
  //TestTemp := AnsiString(test);
  TestTemp := test;
  Result := PAnsiChar(testTemp);
end;

EWeiss 18. Apr 2009 17:27

Re: PWideChar und PAnsiChar
 
Ist das gleiche ..
Hier nochmal meine Funktion geändert.

Delphi-Quellcode:
function BASS_AIMP2VIS_GetName(handle: HVIS): PAnsiChar; stdcall;
var
  PluginInfo: PWideChar;

begin
  Result := nil;

  if (not A_ValidHandle(handle)) then
  begin
    BassFuncs^.SetError(BASS_ERROR_HANDLE);
    Exit;
  end;

  VisInfo := PAIMPVisInfo(Handle);

  BassFuncs^.SetError(BASS_OK);
  PluginInfo := VisInfo^.VisPointer.PluginInfo;

  Result := PAnsiChar(PluginInfo);

end;
Ergebnis ist 'V' sobald PWide nach PAnsiChar konvertiert wird.
Das ändert sich auch nicht wenn ich PluginInfo Global definiere.

gruss Emil

himitsu 18. Apr 2009 17:30

Re: PWideChar und PAnsiChar
 
ich sagte doch, du mußt auch die Daten ändern und nicht nur den Typ :warn:

quasi:
Delphi-Quellcode:
Result := PAnsiChar(AnsiString(PluginInfo));
Delphi-Quellcode:
// Temp{ein AnsiString} := AnsiString(PluginInfo);
Temp{ein AnsiString} := PluginInfo; // dank Autokonvertierung von Delphi auch so möglich
Result := PAnsiChar(Temp);
nur muß das Temp außerhalb der Funktion defniert sein, damit sie nicht bei Funktionsende freigegeben wird.

EWeiss 18. Apr 2009 17:35

Re: PWideChar und PAnsiChar
 
Zitat:

Zitat von himitsu
ich sagte doch, du mußt auch die Daten ändern und nicht nur den Typ :warn:

quasi:
Delphi-Quellcode:
Result := PAnsiChar(AnsiString(PluginInfo));
Delphi-Quellcode:
// Temp{ein AnsiString} := AnsiString(PluginInfo);
Temp{ein AnsiString} := PluginInfo; // dank Autokonvertierung von Delphi auch so möglich
Result := PAnsiChar(Temp);
nur muß das Temp außerhalb der Funktion defniert sein, damit sie nicht bei Funktionsende freigegeben wird.

Ahh .. ;)
Hab das nicht ganz verstanden.
So gehts jetzt!
Delphi-Quellcode:
function BASS_AIMP2VIS_GetName(handle: HVIS): PAnsiChar; stdcall;
var
  PluginInfo: PWideChar;

begin
  Result := nil;

  if (not A_ValidHandle(handle)) then
  begin
    BassFuncs^.SetError(BASS_ERROR_HANDLE);
    Exit;
  end;

  VisInfo := PAIMPVisInfo(Handle);
  PluginInfo := VisInfo^.VisPointer.PluginInfo;

  BassFuncs^.SetError(BASS_OK);
  Result := PAnsiChar(AnsiString(PluginInfo));

end;
Das Teufelszeug in Delphi mit der Konvertiererei. grmmm

gruss Emil

himitsu 18. Apr 2009 17:40

Re: PWideChar und PAnsiChar
 
Delphi-Quellcode:
Result := PAnsiChar(AnsiString(PluginInfo));
Hier hast du nur ein Problem:

Delphi legt da eine interne AnsiString-Variable an, welche in diesem Fall beim End. der Funktion freigegeben wird ... und du hast nur Glück, wenn danach rein zufällig der AnsiTest noch im RAM rumgammelt.

Wie gesagt, du mußt eine externe Variable für die Ansi-Version nutzen.

Nur hast du da ein Problem wenn diese Funktion mehrmals aufgerufen wird, da dann die Daten in der externen Variable nicht mehr konsistent sind.

Wenn nur EINE externe Variable genutzt würde, dann würde hier
Delphi-Quellcode:
P1 := BASS_AIMP2VIS_GetName(H1);
P2 := BASS_AIMP2VIS_GetName(H2);
P1 keine korrekten Daten mehr enthalten, da die für P1 verwendete Temp-Variable inzwischen für P2 verwendet wird.


Probier es mal so und schau was diese Funktion nun für einen Text zurückliefert :zwinker:
Delphi-Quellcode:
function BASS_AIMP2VIS_GetName(handle: HVIS): PAnsiChar; stdcall;
var
  PluginInfo: PWideChar;
  i: Integer;
  S: WideString;
  P: PAnsiChar;

begin
  Result := nil;

  if (not A_ValidHandle(handle)) then
  begin
    BassFuncs^.SetError(BASS_ERROR_HANDLE);
    Exit;
  end;

  VisInfo := PAIMPVisInfo(Handle);

  BassFuncs^.SetError(BASS_OK);
  PluginInfo := VisInfo^.VisPointer.PluginInfo;

  Result := PAnsiChar(AnsiString(PluginInfo));

  for i := 0 to 1000 do
  begin
    S := StringOfChar(WideChar(#123), 50);
    P := PAnsiChar(AnsiString(PluginInfo));
    if P = 123 then ;
  end;

end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:09 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz