Solved

How do I call Dll functions (Written in C)

Posted on 1998-10-26
13
249 Views
Last Modified: 2010-04-06
I would like to call functions from a .dll compiled in C.
I have the .dll itself and the .h file.
I understand I have to write my own .pas file that will include the interface to the .dll.
What shold be the format of the functions there?
How do I use callback functions in that .dll - specifically, how do I send a pointer of one of my (delphi) functions to that .dll?
0
Comment
Question by:tommyq
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
  • 3
  • +2
13 Comments
 
LVL 4

Expert Comment

by:erajoj
ID: 1344468
Hi,
Usually, you would use stdcall, like:
  function ext(value: Integer): Integer; stdcall; external 'mydll.dll' name 'Extfunc';

A pointer to the above function is "@ext".

If you find this troublesome;
send us the .h-file and we will have a look.

/// John
0
 
LVL 4

Expert Comment

by:erajoj
ID: 1344469
Hi,
Usually, you would use stdcall, like:
  function ext(value: Integer): Integer; stdcall; external 'mydll.dll' name 'Extfunc';

A pointer to the above function is "@ext".

If you find this troublesome;
send us the .h-file and we will have a look.

/// John
0
 
LVL 4

Expert Comment

by:erajoj
ID: 1344470
Whooah! My first doublepost ever... ;-)

/// John
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:tommyq
ID: 1344471
Thanks erajoj for the prompt reply.
Let me try and use your double experies in C and Delphi.

Here is the function declerations from the .h file
/*
 * Functions prototypes.
 */
V_NODE __declspec(dllexport) initHeart ( char *heart_fname );
int    __declspec(dllexport) traverseTree ( void *(* callback)( void *x, void *y ), V_NODE tree );
V_NODE __declspec(dllexport) getNextVertex ( V_NODE v, int new_x, int new_y );
void   __declspec(dllexport) getData ( double *V0p, double *total_distp, V_NODE *current_nodep );
void   __declspec(dllexport) destructHeart ( V_NODE *root );
int      __declspec(dllexport)      TestDll ();

VNode is a struct with doubles and pointers.
1. Is this the right way to export the functions?
2. Could you give me an exmple for an apropriate decleration of the function traversTree which recieves a pointer to a callback function?
3. what should be the pascal decleration of the function that is being sent to traverse tree?

Thanks,
Tommy
0
 

Expert Comment

by:DPedrelli
ID: 1344472
interface
function FunctionName(Param1: type; Param2: type): type; stdcall;
implementation
function FunctionName; external; 'DLLName.dll'; name 'CallNameInDelphi';

You may have to check the calling convention but stdcall is standard in C functions.  After the name directive, replace CallNameInDelphi with the name you want to use to call the function in Delphi.
Hope this helps.
David.
0
 

Author Comment

by:tommyq
ID: 1344473
DPedrelli, Sorry for the rejection. I need some more info.

For example, how would I send the C code pointers to my functions, pointers to strings (char * in C = Pchar in Delphi).
How should I store pointers I receive from the called C function?
0
 
LVL 4

Expert Comment

by:BoRiS
ID: 1344474
tommyq

As far as I know you need to use extern or a full function

       eg. of extern

       extern "C" {
       int _EXP MyFunc (int i)
       {
         return (i+10);
       }
       }

       or the function using cdelc

       function MyFunc(i: integer): integer; cdecl; far; external 'MYDLL' index 12;

       you can declare the functions with FAR PASCAL and then call the function in the        normal way.

       If there are problems, make sure that you declare the DLL functions with "_loadds".         Remember that, normally, a DLL function
       runs on the caller's DS, unless you specifically load the correct one.
Later
BoRiS
0
 
LVL 10

Accepted Solution

by:
Lischke earned 60 total points
ID: 1344475
Hi Tommy,

if you always keep in mind that the calling convention in C and Delphi are different then the solution isn't hard to find:

1) function declarations in your interface unit
- V_NODE __declspec(dllexport) initHeart ( char *heart_fname );

   function InitHeart(heart_fname: PChar): V_NODE; cdecl;

- int    __declspec(dllexport) traverseTree ( void *(* callback)( void *x, void *y ), V_NODE tree );

    function traverseTree(Func: TTraverseCallback; Tree: V_Node): Integer; cdecl;

- V_NODE __declspec(dllexport) getNextVertex ( V_NODE v, int new_x, int new_y );
    function GetNextVertex(V: V_Node; New_X, New_Y: Integer): V_NODE; cdecl;

- void   __declspec(dllexport) getData ( double *V0p, double *total_distp, V_NODE *current_nodep );
   procedure GetData(var VOp, total_siatp, current_nodep: Double; cdecl;

- void   __declspec(dllexport) destructHeart ( V_NODE *root );
   procedure destructHeart(root: PV_NODE); cdecl;

- int __declspec(dllexport) TestDll ();
    function TestDLL: Integer; cdecl;

PV_NODE is, as you surely already know a pointer to a V_NODE. The pointers to the double values in GetData can also be PDouble (pointer to double) in case you don't want to use the var key word. But since these parameters seems to be used to pass data back the declaration I've given is appropriate.

2) Specifying implemenation:

const HeartDLL = 'Heart.DLL';

function InitHeart(heart_fname: PChar): V_NODE; cdecl; external HeartDLL;
function traverseTree(Func: TTraverseCallback; Tree: V_Node): Integer; cdecl; external HeartDLL;
function GetNextVertex(V: V_Node; New_X, New_Y: Integer): V_NODE; cdecl; external HeartDLL;
procedure GetData(var VOp, total_siatp, current_nodep: Double; cdecl; external HeartDLL;
procedure destructHeart(root: PV_NODE); cdecl; external HeartDLL;
function TestDLL: Integer; cdecl; external HeartDLL;

If you use exactly the same names in Delphi as they are declared in C (case sensitive!) then you don't need to specify the names again in the external clause.

3) Callback definition:
type TTraverseCallback = function(X,Y: Pointer): Pointer; cdecl;

4) callback implementation:

function TraverseCallback(X, Y: Pointer): Pointer;

begin
  // do something
  Result:=MyValue;
  // etc.
end;

Use then

traverseTree(TraverseCallback,TheNode);

to actually traverse the tree.

If you don't have the source for the DLL then you should expect that there also could be used the stdcall calling convention (as it is used in all system DLLs). If you encounter access violations then try stdcall instead of cdecl.

The memory for the value passed to InitHeard can simply be gotten by declaring a String variable and calling:

MyNode:=InitHeart(PChar(AName));

with

var AName : String;

Anymore questions? Just ask :-)

Ciao, Mike
0
 
LVL 10

Expert Comment

by:Lischke
ID: 1344476
Ooops,

found some typos in the text (the input window here is horrible...).

to 4) the function must also be declared with cdecl

GetData needs a closing parenthesis before cdecl

Ciao, Mike
0
 

Author Comment

by:tommyq
ID: 1344477
Mike,

Thanks for your ELABORATED answer. It is amazing how an expert can help when you are desperate.
I will check it out and let you know.

Thanks again,
Tommy
0
 

Author Comment

by:tommyq
ID: 1344478
Mike,

Thanks.
It worked.
You are great.

Tommy
0
 
LVL 4

Expert Comment

by:erajoj
ID: 1344479
Mike, impressive answer!
If we had an "achiever of the month" award, I would vote for you this month. :-)

/// John
0
 
LVL 10

Expert Comment

by:Lischke
ID: 1344480
;-)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi: Connect to running MS Outlook 4 165
Tvertscrollbox like a whatsapp layout 5 53
MS Access from Delphi 31 81
Delphi Firemonkey : user drawing in window 3 26
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…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
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 …
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial

733 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