A r t i c l e s
|
Clearing Up PChar and DLL Confusion
|
Clearing up some confusion:
- PChar's are not just for alpha-numeric characters, they can include dots and
other symbols too. They are like ansistrings in that sense.
- You can cast a string to a pchar and vice versa in many cases.
i.e. pchar(MyString) and string(MyPchar)
However, when working with libraries (DLL), casting will not work when the
parameter being sent is to be modified.
- using strings in library/executable does work reliably if you use
limited shortstrings. Huge strings, or long strings, or ansi strings are not to be
used unless you use sharemem, or you share memory by calling getmemorymanager(exe)
and setmemorymanager(exe). It is recommended you learn how to use PChar's if you
want to export strings that will be used by other languages, because using Cmem,
Sharemem, or creating your own shared memory manager in the exe will cause the
program to only work with other compilers that have compatible ansistring and
reference counting.
Learning about pchars will also be good education about pointers.. but maybe 50-90
percent of people fail to understand them.
- Pchar knowledge will pay off if you want to build a plug-in system for your
software that is available to other languages without a common ansistring. You will
have a hard time making a generic plug in system without pointer/pchar education.
The windows operating system and the linux libraries are based on pointers and
pchars. The entire OS is basically a plug-in system.
If you are just having one Pascal application interact with another Pascal
application, pchars may be overboard for your needs (but they will still work). You
can use cmem.pp, make your own shared memory manager, or use sharemem in these
cases. A C library can not plug in to work your program even if a shared memory
manager is used, since C does not have a string type.
- PChars are like huge strings or ansistrings - they don't have a length limit.
But you must manage the memory when creating a new pchar buffer that will hold
data. A cast is not a buffer, it is just a read only pchar pointing to a string's
contents.
- Let the program manage the memory of pchar the pchar will be filled or modified
in the DLL.
- using 'var' keyword in front of function/procedure parameters allows the
parameter to be "writable" inside the function code block. Using a "var" keyword in
front of a pchar, however, is not generally needed. A pchar contains original
data it is pointing to, so passing a pchar in without the 'var' keyword still
allows one to modify the pchar data being pointed to. We can modify the pchar's
data in the function without using a var parameter.
You can treat the function/procedure parameters as if they were IN and OUT
"results". They are more powerful than function results, because they allow data
coming IN and going OUT in the same var. Results are meant to offer data OUT and
only OUT, they do not act as incoming variables.
Passing parameters is somewhat like returning a result, except using a var
parameter is more powerful, because you can modify it elsewhere in the program
before and after the function ends.
- "by reference" versus "by value" ? The articles and help regarding 'by
reference' and 'by value' can be quite confusing (some people even go as far as
confusing one with the other, and falsely calling a by value situation a by
reference one.)
To have a "modifiable" or "writable" parameter, which can act like a result,
prefix your function/procedure parameter with "var". This is "by reference"
parameter. Except if you are using pointers or pchars, since they point to data -
they aren't the data themselves.
To have a "read only" or "non-writable" and "by reference" function parameter,
prefix your function/procedure parameter with "const". When using pchar's, you do
not need to prefix them with anything: they are special, and are already a
reference to memory.
- What exactly is a function result? i.e. what is the real difference
between a function result, and a parameter? A function result (return value) is
somewhat similar to a "by value" parameter. A function result is not like a
"by reference" parameter, because a Var parameter is a reference, whereas a result
is more like a copy or by value parameter. The caller of the function allocates a
variable which will hold a copy of the result.
-
When pchar's are used as function results, it gets confusing, and this is why pchar
results are not often seen in fpc/delphi code.
The result is like a "magic" local variable, and this magic local variable is not
as controllable as a parameter. These magic local variables called results work for
every day programming in unit files - but when it comes to DLL's and exporting,
pchar's as results are confusing, and should generally be used less.
The caller exe cannot control the function result like it could with a parameter,
and this is bad. This is because the function result is not a reference to the
variable we give the function - rather the result is created like a local variable
in the function. The caller EXE program cannot allocate the function result memory
on the calling side - the memory must be allocated on the DLL side. With a var or
by reference parameter, the caller exe program can allocate the parameter memory on
the calling side, and free it there too.
Integers, however, can be returned as function results in DLL/EXE communication.
Although a function result is similar to a by value parameter since it is like
copy, is still different than a by value parameter in other ways. A by value
parameter makes a copy of the incoming parameter before the function block code
executes, then this copy can be used in the function. A function result, however,
does not make a copy of your existing variable first. The function result is a
magic variable allocated, and then a copy of this magic variable is given to the
variable on the calling side. This is because a function result is not a
parameter - parameter's have different purposes than results, and results are not
meant to be incoming parameters.
A function result therefore is copied to your variable you have provided, when the
function is done . On the other hand, a by value parameter makes a copy before the
function activity occurs so that you can use the data in the function.
So as one can see, a function result is similar to a "by value" parameter in that
they are copies of something - but they are different in that the copying takes
place for different purposes at different times.
- PChar's and shortstrings can be used by programs written in other languages.
C and C++ programmers may be more familiar with PChar's, but they should also know
what a shortstrings is (a Pascal string). It is said, for example, that even old
versions of Microsoft Excel may have used limited length Pascal like strings (for
speed or other reasons) even though it was written by C/C++ programmers.
- Do not allocate memory using a function such as StrAlloc on the calling side and
then free the same string on the library side. Always allocate and free on the
same side. That means you call StrAlloc and Dispose from the EXE side only, or the
DLL side only. Generally, it is best to do it from the EXE side.
- Allocating memory and freeing it on the DLL side is not the usual practice. It
can be done, but it is not really wise to do so. The EXE should control the memory.
- The reason for the above has to do with code organization. If a New is called
then a Dispose must follow. But if a New is called on the EXE side and a Dispose
is called on the DLL side, then code becomes confusing because the programmer does
not see a New and Dispose pair together in the same program.
- It is not always true that a const parameter will conserve memory or offer speed
advantages, but usually on large records or variables, and in general, it should
save memory since it is just a reference to something rather than making a copy
like a by value parameter would.
- Some languages do not even offer by reference or by value choices. Some
languages choose one or the other. Pascal is powerful in that it offers you both,
but since Pascal is powerful with the choice of by reference vs by value, this can
also confuse the programmer.
Confused, or clear? It is normal for the reader to be confused about pchars, by
reference, and by value. Once you know and understand them, you will build the most
powerful, strong, and robust plug-in architectures and frameworks.
See also: MD5Hash Example, Passing PChars in Libraries
|
|
About
This site is about programming and other things.
|