Solved

Calling a C++ DLL from Delphi 3

Posted on 1998-02-23
7
612 Views
Last Modified: 2010-04-04
Hi...
  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)
rc
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.
pdqparms
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"
source_buffers
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
buffers.
PDQSORT_BUFFER sbs[3];
/* 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 */
target_buffers
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.
input_exit
is an optional pointer to a user-written input exit procedure. If no input exit
is present, then a NULL value must be passed.
output_exit
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?

Thanks...
   Shawn Halfpenny
   drumme59@sprint.ca
0
Comment
Question by:aztec
  • 4
  • 3
7 Comments
 
LVL 5

Accepted Solution

by:
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:

var
  pdqparms : array[0..255] of char;
begin
  // 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');
end;


May this help
Igor
0
 

Author Comment

by:aztec
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!

Cheers!
   Shawn Halfpenny
   drumme59@sprint.ca
0
 
LVL 5

Expert Comment

by:inter
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?

IF

** 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
Igor


0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:aztec
ID: 1359737
Igor...
   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.

Cheers
   Shawn
   drumme59@sprint.ca
0
 
LVL 5

Expert Comment

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

inter@kosgeb.tekmer.gov.tr
Bye
Igor
0
 

Author Comment

by:aztec
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' !

Cheers
   Shawn Halfpenny
0
 
LVL 5

Expert Comment

by:inter
ID: 1359740
Thanks friend,

I am happy for the problem is over.

Bye and regards,
Igor
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

747 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now