Forum > Windows

Windows API and wide/unicode strings

(1/5) > >>

Nadar:
I need to make a small NSIS plugin ("C style DLL"), and chose Lazarus/FPC for the job because my C/C++ knowledge is terrible. I don't write much Pascal these days, but I used to code in Delphi back in the days.

I'm sure this has a very simple solution, but I seem to be incapable of figuring it out. I need to build both "Unicode" and "Ansi" versions of the DLL, since NSIS itself can run in "both modes". "Unicode" here means that all strings are "Windows wide strings" aka 16 bit chars. My problem is how to make sure that all "external" string handling use one or the other type based on the chosen "build mode". I've defined a custom compiler option "-dUNICODE" for the "Unicode" build, which seems to make some things happen.

But not all. In particular, I'm currently struggling with "TLVITEM" defined in "struct.inc". It points to "LV_ITEM" which is a record where one of the fields is a string - "pszText". It is defined as a "LPTSTR" - which is defined as either "Pchar" or "Pwidechar" depending on the "UNICODE" define. But, whatever I do, I can't seem to get it to actually USE that "UNICODE" version, so I get a compile error if I try to assign a PWideChar to "pszText" in "Unicode build mode".

I've searched and read lots and lots about string types, encodings etc - with lots of discussions about the different encodings - but I've not managed to find anything that points me in the right direction as to how to get the compiler to "use the types I want".

Any help/hints are appreciated.

AlexTP:
Maybe you can show _small_ project, which has problems you told?
And: -dUnicode define applies to your project, not to LCL.

Nadar:
As to the example, I think https://nsis.sourceforge.io/Examples/Plugin/nsis.pas shows the essentials. This unit takes care of the "interface" between the NSIS caller and the DLL - all the rest is essentially "normal Pascal code". I'm currently trying to make "nsis.pas" work correctly with and without wide strings - and the location which is commented with "Unicode bug?" is the location that gives the compile error because of the type "confusion" if I try to cast to for example PWideChar instead of PChar (the cast might not be "valid", I don't really have enough overview over implicit conversions to tell - but the problem is the same if I create a new PWideChar local variable and try to assign it).

For completeness, here's an example code that uses the "nsis.pas" unit - but I really don't think that is relevant to this problem: https://nsis.sourceforge.io/Examples/Plugin/exdll_with_unit.dpr


--- Quote from: AlexTP on November 22, 2023, 06:50:25 am ---And: -dUnicode define applies to your project, not to LCL.

--- End quote ---
This might be something. As I'm quite unfamiliar with Lazarus - the LCL, RTL etc references are confusing. I don't know which files are and aren't part of these "components". Since this plugin is to provide logic/functions only, it will have no graphics and as such I'd think that I didn't use the LCL at all? I don't use and "components" or have any forms. The RTL on the other hand I assume is always involved somehow - and if "struct.inc" and "base.inc" is precompiled it explains why nothing I do has any impact. But, that begs the question why does "base.inc" use "Unicode ifdefs" if there's no way to "activate" them? The definition of "LPTSTR" seems to be the crux of this exact problem, lines 185-190 in "my version" of "base.inc".

Nadar:
If the problem is the precompiled parts - is there anything I can do do make that code with the "UNICODE" define "active"? Or do I have to define my own structures, API calls etc "in parallell" and not actually use the standard libs to make this work?

Remy Lebeau:

--- Quote from: Nadar on November 22, 2023, 06:36:30 am ---But not all. In particular, I'm currently struggling with "TLVITEM" defined in "struct.inc". It points to "LV_ITEM" which is a record where one of the fields is a string - "pszText". It is defined as a "LPTSTR" - which is defined as either "Pchar" or "Pwidechar" depending on the "UNICODE" define. But, whatever I do, I can't seem to get it to actually USE that "UNICODE" version, so I get a compile error if I try to assign a PWideChar to "pszText" in "Unicode build mode".

--- End quote ---

I may be wrong here, but TLVITEM is likely pre-compiled based on whether the RTL/LCL itself is built in ANSI or UNICODE mode, regardless of whether your project is built in ANSI or UNICODE mode.  That would explain the error you are seeing.

So, you will have to instead use TLVITEMA/LPSTR or TLVITEMW/LPWSTR explicitly, based on your project's build mode.

Navigation

[0] Message Index

[#] Next page

Go to full version