A r t i c l e s
Navigation

Note: This site is
a bit older, personal views
may have changed.

M a i n P a g e

D i r e c t o r y

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.
_ _ _