Link to home
Start Free TrialLog in
Avatar of mikkon
mikkon

asked on

Using external DLL's from Delphi

A vendor of mine has a Delphi-based system to which I must integrate a simple application. My application is developed in C, so the simplest way would be to modify the application so that it becomes a DLL, which would export a function that could be used from Delphi.

My application needs one string as input, and it outputs another string. I need to know the following:

1. How to build the DLL (in C) so that it can pass strings to/from Delphi? Can I use normal NULL-terminated strings as follows:

void _cdecl ExternalFunction(char *InputString, char *OutputString);

2. Given this DLL, how can I call it from Delphi? Please provide specific lines of code (including declaration and the actual call), because I don't know Delphi at all.
ASKER CERTIFIED SOLUTION
Avatar of dwwang
dwwang

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ZifNab
ZifNab

do you want that a delphi program uses your dll, or that Delphi itself uses your component?
Sorry, the call statement shold be:

ExternalFunction(input,output);

and also if you need the inputstring to be initialized, just write like:

input:='My Input String Here...';
just wanted to refer to this dwwang :-)
Thanks, Zif :-)
Avatar of mikkon

ASKER

Thanks, dwwang! Just let me know if I got this straight:

In C, I declare my function as follows (changed from the original case to include a return status and use __stdcall; any problems with __stdcall?):

int _stdcall ExternalFunction(char *input,char *output)

And in Delphi as follows:

function ExternalFunction(Input,Output:PChar):WORDBOOL; stdcall; external 'mydll.dll' name 'ExternalFunction';

Then I call it as follows:

var Input,Output:PChar;


Input:="...";
Output:="1234567890123456";    { Needed to inialize the output string to a certain length??? }
retval:=ExternalFunction(Input,Output);

Is this right? Does Delphi handle NULL-terminated strings just like C? I tried this kind of external function with Visual Basic, but it didn't recognize NULLs correctly (for example, Output&"test" didn't produce the expected output).

Hi mikkon,

PChar = null-terminated string in Delphi!

here information :

A string literal is assignment-compatible with the PChar type. This means that a string literal can be assigned to a variable of type PChar. For example,

var
 P: PChar;
 ...
begin
 P := 'Hello world...';
end;

The effect of such an assignment is that the pointer points to an area of memory that contains a null-terminated copy of the string literal. This example accomplishes the same thing as the previous example:

const
 TempString: array[0..14] of Char = 'Hello world...'#0;
var
 P: PChar;
 ...
begin
 P := @TempString;
end;

You can use string literals as actual parameters in procedure and function calls when the corresponding formal parameter is of type PChar. For example, given a procedure with the declaration

procedure PrintStr(Str: PChar);

the following procedure calls are valid:

PrintStr('This is a test');
PrintStr(#10#13);

Just as it does with an assignment, the compiler generates a null-terminated copy of the string literal. The compiler passes a pointer to that memory area in the Str parameter of the PrintStr procedure.
Finally, you can initialize a typed constant of type PChar with a string constant. You can do this with structured types as well, such as arrays of PChar and records and objects with PChar fields.

const
 Message: PChar = 'Program terminated';
 Prompt: PChar = 'Enter values: ';
 Digits: array[0..9] of PChar = (
   'Zero', 'One', 'Two', 'Three', 'Four',
   'Five', 'Six', 'Seven', 'Eight', 'Nine');
Hi,  mikkon

Firstly, Delphi can handle Null terminated string just as in C/C++, Delphi is definitely better than VB in such kind of issues.

The second, you need to allocate memory to the outputstring, either as you said(to assign a fixed length string to it), or as Zif suggested, to define a array of characters and assign the address to it.

By the way, I think you should use strcopy or some thing like that(in C) in your DLL to pass the value pack to Delphi, right?
Avatar of mikkon

ASKER

Thanks to both dwwang and ZifNab! And yes, I am using strcpy() to copy the output string in C. The idea is to use pointers to Delphi's memory in the C code.