Calling a C++ DLL from Delphi 3

Posted on 1998-02-23
Last Modified: 2010-04-04
  I'm trying to call a 3rd party sort routine which is in the form of a C++ DLL. The documentation included in v3 really stinks on this topic. My app is called MYAPP.EXE. Anyway, here's what I'm doing:

First the C++ DLL I'm trying to call is the file 'pdqsort.dll'. The function within that file is 'pdqsort'.Also included with this is a pdqsort.lib file...which I don't know if I need or not. Here is a snippet from the Pdqsort manual on how to call this DLL:

Application Program Interface
Pdqsort is invoked when a user-written program uses the following interface. "PdqSort" is the name of the entry
point, but "SMARTsort" can be used instead, since the interface is SMARTsort-compatible.
rc = PdqSort ( pdqparms, source_buffers, target_buffers, input_exit, output_exit, NULL, NULL)
is the return code from Pdqsort. A value of zero indicates success. A non-zero
value indicates either an error or an unusual situation. The value generally
corresponds to the most recent error message number generated by Pdqsort.
See the chapter on "Messages" for further details.
is a pointer to a null-delimited string in memory. The string should contain valid
Pdqsort parameters that are described in the "Parameters" chapter.
char * pdqparms = "-x'format key char 8 char 72'
-k key -o output.file input.file"
is an optional pointer to a sequence of one or more PDQSORT buffer
structures, described below. If no source buffers are passed then a NULL
pointer must be specified. All buffer structures must reside in contiguous
memory, terminated by a word containing binary zeroes (a NULL). There need
not be any relationship between the number or size of any target and source
/* Pass 15 records in two different memory areas */
sbs[0].buffer = memory_ptr_1;
sbs[0].buffer_size = 80*8; sbs[0].nbytes_used = 0;
sbs[1].buffer = memory_ptr_2;
sbs[1].buffer_size = 80*7; sbs[1].nbytes_used = 0;
sbs[2].buffer = NULL; /* End of list indicator */
is an optional pointer to a sequence of one or more PDQSORT buffer
structures. If no target buffers are passed then a NULL pointer must be
specified. All buffer structures must reside in contiguous memory, terminated
by a word containing binary zeroes (a NULL). There need not be any
relationship between the number or size of any target and source buffers. If
no output file is used, then the target buffers must be large enough to hold the
sorted records. Pdqsort will fill the target buffers in the order listed. Records
may span target buffers.
is an optional pointer to a user-written input exit procedure. If no input exit
is present, then a NULL value must be passed.
is an optional pointer to a user-written output exit. If no exit is present, then
a NULL value must be passed.
The final two NULL pointers are reserved for future use.

..The folks at pdqsort told me that all these variables in the pdqsort function call are pointers to strings, and the only one I need to worry about is the first one. The rest I can just set as NULL pointers.

OK,now in my Delphi program I put this code in my main Unit in the "Implementation" section (is this correct?)

function PdqSort(pdqparms:ptstr; s_buf:ptstr; t_buf:ptstr; i_exit:ptstr; o_exit:ptstr; null1:ptstr; null2:ptstr): integer; far; external 'pdqsort.dll';

(I declare ptstr as ...ptstr = ^string;)

..Later on in my unit I call the DLL like so:

pdqparms^:='-z 80 -u -o '+ homedir + 'inpsort.txt '+ input_str;
result := PdqSort(pdqparms, s_buf, t_buf, i_exit, o_exit, null1, null2);

..I compile and build it ok, but when I go to run it, it comes up with an error window: "Error Starting Program: The MYAPP.EXE file is linked to missing export PDQSORT.DLL:PdqSort

..When I click OK on that error, there's another one right underneath it saying "Error: Unable to create process".

What am I doing wrong...DLL's are confusing enough, let alone trying to call a 3rd party's one, where you can't get into the source code in order to see how the heck they have it set up. Can you help?

   Shawn Halfpenny
Question by:aztec
  • 4
  • 3

Accepted Solution

inter earned 50 total points
ID: 1359734
Important notes:

Pointer to string does mean NULL terminated string in C++ in general so, your decleration above is incorrect. So they most likely be PChar;(it is known in delphi, you do not need to declare it). Another important think is DLLs exports functions in stdcall model. So the function be

Function PdqSort(pdqparms, s_buf, t_buf, i_exit , o_exit, null1, null2: PChar): integer; stdcall; external 'pdqsort.dll';

Here is an example how to declare a null terminated string:

  pdqparms : array[0..255] of char;
  // delphi automatically understands that this is a
  // null terminated string and append #0 to the end
  pdqparms = '-x''format key char 8 char 72''-k key -o output.file input.file'
  if PdqSort(pdqparms, nil, nil, nil, nil, nil, nil)<> 0 then
     ShowMessage('Error in pdqsort');

May this help

Author Comment

ID: 1359735
Hello Igor...
  I have done all you suggested and it compiles and builds OK,  however I am STILL getting those same error windows when I try to run it. There must be something fundamentally wrong with what I'm doing or somehow it cannot find the pdqsort.dll file. I'm stumped.

Hope you have more suggestions!

   Shawn Halfpenny

Expert Comment

ID: 1359736
Hi Aztec,

1 - Are you SURE this DLL is a 32 bit DLL(rightclick and quickview on it in explorer and look at the header)?

2 - When program start is it stucked just in the begining of the .DPR file before creating any forms and calling application.Run?


** Q1 - NO
  We should use somekind of thunking if this is the case

** Q1 - YES AND Q2- YES
  We still can not give the prototype(external decleration ) correctly. We should fix it.

** Q1 - YES AND Q2- NO
  Dont wory, we (DELPHI actualy) have succesfully, dynamically link to the DLL. We have a parameter format problem.

Please respond

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.


Author Comment

ID: 1359737
   What is your e-mail address? I will e-mail you the DLL (only 201K), and you can try to call it from a Delphi app...ok? This will save us both a lot of time and questions.


Expert Comment

ID: 1359738
Sure but, give an example to the pdgparams since I do not have the documentation?

Author Comment

ID: 1359739
Hello Igor...
   We finally figured out how to get thru to that C++ DLL. The maker of the DLL had to fix things on his end! Thanks for all your effort on this problem. Did I give you a grade yet on this? If not, give yourself an 'A' !

   Shawn Halfpenny

Expert Comment

ID: 1359740
Thanks friend,

I am happy for the problem is over.

Bye and regards,

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to fill array with TArray.Create? 14 90
Dev Express grid collapse 2 45
LAN or WAN ? 11 92
how can i search if string exist in array ? 3 59
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question