I am trying to use NPAPI Framework from Yury Sidorov by following this answer:
How to embed Delphi VCL form into HTML page using NPAPI
but I get an error with NPPlugin.pas. I am using delphi XE7 and here what i did by following Krom Stern instructions
procedure DefDebugOut(const Msg: string);
begin
OutputDebugStringA(PAnsiChar(Msg + #13#10)); // Changed From Pchar To PAnsiChar
end;
but still getting error with compiler with this message
[dcc32 Error] NPPlugin.pas(2215): E2010 Incompatible types: 'PWideChar' and 'PAnsiChar'
Error raised on this procedure
procedure TPlugin.SetException(const msg: string);
var
s: String;
begin
try
{$ifopt D+} NPP_DebugOut('Exception: ' + msg); {$endif}
s:=UTF8Encode(msg);
NPN_SetException(m_pScriptableObject, PAnsiChar(s));
except
{ prevent any exception from leaking out of DLL }
end;
end;
here is the procedure NPN_SetException
procedure NPN_SetException(npobj: PNPObject; msg: PNPUTF8);
begin
NavigatorFuncs.SetException(npobj, msg);
end;
This NPAPI code was clearly designed for older versions of Delphi before the switch to Unicode in Delphi 2009. The default String
/(P)Char
types are no longer aliases for AnsiString
/(P)AnsiChar
, they are now aliases for UnicodeString
/(P)WideChar
. A UnicodeString
cannot be casted to a PAnsiChar
, just like an AnsiString
could never be casted to a PWideChar
.
In DefDebugOut()
, the simplest fix is to change PAnsiChar
to PChar
and change OutputDebugStringA()
to OutputDebugString()
:
procedure DefDebugOut(const Msg: string);
begin
OutputDebugString(PChar(Msg + #13#10));
end;
This is compatible with all Delphi versions (the code should have been doing this from the beginning - there was no reason to call OutputDebugStringA()
directly). PChar
and OutputDebugString()
map to PAnsiChar
and OutputDebugStringA()
in Delphi 2007 and earlier, and to PWideChar
and OutputDebugStringW()
in Delphi 2009 and later. So everything matches.
In TPlugin.SetException()
, UTF8Encode()
returns a UTF8String
in all versions of Delphi. However, prior to Delphi 2009, UTF8String
was just an alias for AnsiString
itself, but in Delphi 2009 it was changed to a true UTF-8 string type with full RTL support (it still has an AnsiString
base, so it can still be casted to PAnsiChar
). When a UTF8String
is assigned to a UnicodeString
, the compiler performs an implicit data conversion from UTF-8 to UTF-16. And as stated above, UnicodeString
cannot be casted to PAnsiChar
. So you need to change the s
variable from String
to UTF8String
for all Delphi versions:
procedure TPlugin.SetException(const msg: string);
var
s: UTF8String;
begin
try
{$ifopt D+} NPP_DebugOut('Exception: ' + msg); {$endif}
s:=UTF8Encode(msg);
{
UTF8Encode() is deprecated in Delphi 2009+.
In those versions, you can use this instead:
s := UTF8String(msg);
}
NPN_SetException(m_pScriptableObject, PAnsiChar(s));
except
{ prevent any exception from leaking out of DLL }
end;
end;
With that said, if you are still getting the same error on the NPN_SetException()
call, then it means the second parameter of NPN_SetException()
is declared as PChar
. It needs to be declared as PAnsiChar
instead.