Delphi Programming
Explore
Main Page
All Pages
Community
Interactive Maps
Recent Blog Posts
Top Content
most_popular
most_visited
Delphi 7
Object Pascal
Delphi 6
Creating DLLs
Simple Calculator Tutorial
Delphi 2007 for Win32
Delphi 8
highest_ratings
newly_changed
3rd Party Components
Delphi 7
Good Quality Applications Built With Delphi
Delphi Release Dates
Open Paradox db without password
RTLVersion Constant
Borland Compiler Conditional Defines
Community
top_users
Community portal
forum
Recent blog posts
FANDOM
Fan Central
BETA
Games
Anime
Movies
TV
Video
Wikis
Explore Wikis
Community Central
Start a Wiki
Don't have an account?
Register
Sign In
Sign In
Register
Delphi Programming
2,929
pages
Explore
Main Page
All Pages
Community
Interactive Maps
Recent Blog Posts
Top Content
most_popular
most_visited
Delphi 7
Object Pascal
Delphi 6
Creating DLLs
Simple Calculator Tutorial
Delphi 2007 for Win32
Delphi 8
highest_ratings
newly_changed
3rd Party Components
Delphi 7
Good Quality Applications Built With Delphi
Delphi Release Dates
Open Paradox db without password
RTLVersion Constant
Borland Compiler Conditional Defines
Community
top_users
Community portal
forum
Recent blog posts
Editing
Creating DLLs
(section)
Back to page
Edit
Edit source
View history
Talk (7)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
=== Passing strings === So, in order to allow strings to be passed between an application and a DLL you must take extra care. Actually, the easiest way is just to not allow it at all! Now I can hear you thinking: "WTF is this guy talking about? Of course I want to pass strings from my application to the DLL file!" Yes, you would want to, wouldn't you? But you usually don't want to pass strings, but you want to pass the series of characters that are stored in a string. To do that you use something that comes from the ancient times when people where using primitive programming languages like C that didn't know such sophisticated data structures as strings (yes, I know, you C fanatics. C can do everything given the right libraries. This is meant to be a joke.). Back then programmers were stuck with something called zero-terminated strings or rather "a pointer to a array of characters which ends with the special character NUL". In Delphi that's called a PChar. ==== Exporting a string function ==== Now let's load our library project again and add a new function to it: function CountChars(_s: Pchar): integer; StdCall; begin Result := Length(_s); end; Notice something? No? Look closer? Still nothing? OK, I'll tell you: You know what the Length function does, don't you? It returns the number of characters stored in a string. But what do we pass to it? What is the parameter _s declared type? It's ''PChar'', not String! Welcome to the conveniences of Delphi: It automatically converts a PChar to a string when assigning it to a string or passing it to a function expecting a string parameter. I hope you also noticed that we declared our new function as StdCall again. You should never forget to explicitly add a calling convention. If you run into access violations when calling a DLL function, that's the first thing to check: Do your program and your DLL file both use the same calling conventions? If not, you found the problem. We export the new function just the same way we exported the other one. You end up with a project source like this: library MyFirstLibrary; uses SysUtils, Classes; {$R *.res} function AddIntegers(_a, _b: integer): integer; stdcall; begin Result := _a + _b; end; function CountChars(_s: Pchar): integer; StdCall; begin Result := Length(_s); end; exports AddIntegers, CountChars; begin end. Save your changes and compile the project. ==== Calling a string function ==== Now we want to call that new function. So close the library project and open your test project again. Add the following function declaration: function CountChars(_s: Pchar): integer; StdCall; external 'MyFirstLibrary.dll'; and the following code to the main program: WriteLn(CountChars('hello')); Now your program should look like this: program MyLibraryTest; {$APPTYPE CONSOLE} uses SysUtils; function AddIntegers(_a, _b: integer): integer; stdcall; external 'MyFirstLibrary.dll'; function CountChars(_s: Pchar): integer; StdCall; external 'MyFirstLibrary.dll'; begin WriteLn(AddIntegers(1, 2)); WriteLn(CountChars('hello')); Write('Press Enter'); ReadLn; end. Again, notice something? Not? Look closer! What type of parameter do we pass to CountChars? Yes, that's a string constant! Welcome to the conveniences of Delphi again: Delphi automatically converts string constants to PChars if you pass them to a function that expect PChars. Compile and run your program. You should now get another output line saying "5", which incidentally is the number of characters in the string 'hello'. Now, was that painfull? You didn't technically pass a string, but for all practical purposes you did. Now let's try to pass an actual string, not a string constant. Declare a vaiable ''s'' and assign your name to it: var s: string; begin s := 'your name'; WriteLn('"', s, '" contains ', CountChars(s)); Write('Press Enter'); ReadLn; end. Compile and run it ... Oh? WTF? It doesn't compile. Welcome to the inconveniences of using PChars! Delphi does not automatically convert strings to PChars (don't ask me, why). You have to explicitly tell it to do that by typecasting. So change your code to: WriteLn('"', s, '" contains ', CountChars(PChar(s))); Compile and run it. You should now get an output like this: "your name" contains 9 characters Press Enter
Summary:
Please note that all contributions to the Delphi Programming are considered to be released under the CC-BY-SA
Cancel
Editing help
(opens in new window)
Follow on IG
TikTok
Join Fan Lab