I'll start with a piece by piece breakdown of what we can see. Bear in mind that we don't have NPPlugin.pas
at hand and have to infer its contents from the information in the question. All the same, I think it's possible for us to do that accurately.
s := UTF8Encode(msg);
Here s
is of type string
. That's an alias for UnicodeString
, encoded as UTF-16. So you convert from UTF-16 to UTF-8 and then back to UTF16.
You need it like this:
NPN_SetException(m_pScriptableObject, PAnsiChar(UTF8Encode(msg)));
Alternatively, if you need a variable to hold UTF-8 encoded text, declare it to be UTF8String
which is AnsiString(65001)
. If you changed the type of s
to be UTF8String
then the code in the question would be correct. Although somewhat more verbose than it would need to be.
Another problem is here:
OutputDebugStringA(PAnsiChar(Msg + #13#10));
Your cast doesn't make Msg
actually be 8 bit encoded. However, you don't want to use the ANSI version of the function. You need this:
OutputDebugString(PChar(Msg + sLineBreak));
Your exception handler is misguided. It is the DLL's job not to leak exceptions. If you attempt to catch and suppress them all you will simply mask errors in your own code. You need to remove that exception handler and check for errors by following the instructions given by the library documentation.
Now to the bigger picture. None of the above explains your reported error. The only sound explanation for that is that your declaration for NPN_SetException
accepts wide text. In which case you could make the code compile simply by writing this:
NPN_SetException(m_pScriptableObject, PChar(msg));
Of course, that makes the appearance of UTF-8 somewhat inexplicable. In fact the library Mozilla does accept 8 bit text, UTF-8 encoded. So why would NPN_SetException
expect to be passed UTF-16 text? Well it doesn't. The explanation is that you have declared NPN_SetException
incorrectly. So, just to be clear, whilst PChar(msg)
would make your code compile, it would not resolve your problem. You would be left with code that failed at runtime.
So, how did this happen? You've taken a working piece of code that used PChar
aliased to PAnsiChar
onto a Delphi with PChar
aliased to PWideChar
and not translated correctly. Even when you get your code to compile, it will not work correctly. You started with code like this:
function NPN_SetException(..., Msg: PChar): ...;
On older Delphi versions where PChar
was PAnsiChar
then this was correct. You are compiling this now on XE7 where PChar
is PWideChar
and so this is not correct. It needs to be:
function NPN_SetException(..., Msg: PAnsiChar): ...;
Then the calling code can be:
NPN_SetException(m_pScriptableObject, PAnsiChar(UTF8Encode(msg)));
My advice is that you:
- Step back and revisit the handling of Unicode in Delphi.
- Go back to you original code and change all the Mozilla interface code that uses
PChar
to PAnsiChar
.
- Whenever you need to provide
PAnsiChar
do it with PAnsiChar(UTF8Encode(str))
.
DefDebugOut
compiles, although it is clearly wrong. – Aweinspiring