Solved

How do I call Dll functions (Written in C)

Posted on 1998-10-26
13
240 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
  • 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi XE10, DigitalPersona Fingerprint reader and MySQL 6 220
IdTelnet1DataAvailable handler freezes the Application 4 68
Convert Jpg /PNG To GIF 5 120
CheckListBox usage 3 51
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
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…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …

895 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

14 Experts available now in Live!

Get 1:1 Help Now