Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


converting C header to delphi; callback function definition in delphi

Posted on 2006-06-27
Medium Priority
Last Modified: 2010-04-05
Dear Experts!

I have a C DLL that I call from my delphi project. So far, so nice. I used dr.bob's headconv to get the header file converted to a delphi pas but needed to change some things manually to get the main functions in this DLL to work from my delphi project.

Now I run into 2 problems that I can't resolve by now.

At the beginning of the header file I have this define block, that is not correctly converted to the pas by headconv - bds2006 just says its unkown:

#define LIBNAME_API __declspec(dllexport)
#define LIBNAME_API __declspec(dllimport)

Where LIBNAME_API is used in this way in the C header:

LIBNAME_API int _stdcall call_libname_conv(char *inbuf, int inlen, char *outbuf, int outlen);

I just rewrote it to this in my delphi pas (statically example):

function call_libname_conv(inbuf: PChar;
                          inlen: Integer;
                          outbuf: string;
                          outlen: Integer): integer cdecl  {$IFDEF WIN32} stdcall {$ENDIF};

This works, but I wonder what the hell was the '__declspec(dllexport)'/'__declspec(dllimport)' means and if I should use it in delphi?!
A remark: I have an obvious memory leak in the DLL when I use it in my delphi project. The vendor of the DLL assured me, that he can't reproduce this
leak in his environment (I believe him, because he is very supportive). Could this be caused because of this 'wrong' conversion from the c header to my pas??


I this C header, there is an callback function (hope this is the correct name for this):

/* Progress function gets progress information, 0.0 to 100.0 ("percent") */

LIBNAME_API int _stdcall setProgressFunction(int (__stdcall *myProgressFunction)(float));

How should I convert this to pascal? I assume 'myProgressFunction' would be one of my delphi functions that is called back from the DLL and shows something like a progress bar?! How should this function call look in my pas and how should my own 'myProgressFunction' look like (just the definition)??

I know you are experts, so I'm sure there are many peoples out that are able to solve this two problems ;)

Many thanks in advance!!

Question by:real_icecoke
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
  • 2
  • 2
LVL 28

Accepted Solution

2266180 earned 1000 total points
ID: 16992112
for the second problem:

type myprogressfunc(p:float):integer; stdcall;

function setProgressFunction(f:myprogressfunc):integer; stdcall; external "blala.dll";// if using static linking. if you are loading the dll dinamically, skip this one.

function myprogress(p:float):integer; stdcall;
// do whatever


for the first problem (and second):
also, I don' know if you need the cdecl. try without it and see if yo are getting any memory leaks.

the thing with the __declspec(dllexport)'/'__declspec(dllimport)' means and if I should use it in delphi?!
is that the header is used both in the program and in the dll. so the dll defines LIBNAME_EXPORTS which means that the functions will be exported and hence need the dllexport thingie.
on the otehr heand, if you use the header from your program (C) then you don't define LIBNAME_EXPORTS so it will use the dllimport.

that's about it. also, you cannot use 2 calling convensions (like you do in your case, cdecl and stdcall. you need to only use one.
LVL 26

Expert Comment

by:Russell Libby
ID: 16992379
Just as a confirmation, you should only be using stdcall:

>> LIBNAME_API int _stdcall call_libname_conv(char *inbuf, int inlen, char *outbuf, int outlen);

the _stdcall indicates that the function shall use the stdcall convention (regardless of importing/exporting the function). If you wanted to duplicate the defines in the code, then the following would be one way to do it in Delphi:

  LibName           = 'the_library.dll'; // Correct this with the import library name

function call_libname_conv(inbuf: PChar; inlen: Integer; outbuf: PChar; outlen: Integer): Integer; stdcall; {$IFNDEF LIBNAME_EXPORTS} external LibName; {$ENDIF}

The points belong to ciuly on this one though.



Author Comment

ID: 16994594
Thanks to both Russel and ciuly for the fast answer!

So, Q1 ist solved for me - thanks!
Regarding Q2 I tried to use and understand ciuly's example but failed at all. It seems that I have no clue where to place what in a unit. And further more I have to ask myself how the setProgressFunction is used. Do I have to call it, while other routines are running from this DLL (its a file conversion DLL and I assume setProgressFunction shows the state of processing) or is the DLL calling my 'myprogress(dPerct: double)' on its own??

Ciuly, do you have the time to show me a small, but functional example unit for this? Would be great!

Thanks again!
LVL 26

Assisted Solution

by:Russell Libby
Russell Libby earned 1000 total points
ID: 16994761

The defs would be similar to:

// Function prototype
  TProgressFunc  =  function(F: Single): Integer; stdcall;

// Imported function from library
function setProgressFunction(ProgressFunc: TProgressFunc): Integer; stdcall; external 'the_library.dll';

// ... other imported functions, etc...

{$R *.DFM}

// Your callback function
function MyProgress(F: Single): Integer; stdcall;
  // do whatever


You are then expected to call setProgressFunction in your program somewhere, passing it the function address that you wish to be called when some progress has occurred. In the above example, the MyProgress function is the desired callback, and to use it:

// Program code

// Tell the dll what function to call back on

// Make some call to the dll that will cause the callback function to be executed

The dll will then call your function MyProgress, where you can whatever it is you want to do. Also, it is pretty hard for any of us to provide a functional example without an actual library (and documentation) to program against.



Author Comment

ID: 17002374
Yep, that is what a dopey guy like me understands ;)
Thanks to both of you! Even if Russel stated the points belong to ciuly, I will split the points, because Russel achieved to make a blind guy seeing :)

Anyway, again thanks to both giving great answers again!


Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Suggested Courses

604 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