3
votes

So, I have a set of interdependent .c and .h files, and I'm trying to figure out exactly how C/C++-to-Pascal works (my delphi/pascal work otherwise was pretty basic). The c files are steps 1-N (in order) of a mathematical algorithm (each one is a separate function), one header specifies the variables used in each function (I'm using record to recreate the .h files in delphi), and the other header details a custom variable type. The goal is to access the functions without having to re-write the C code into Pascal/Delphi syntax, linking from delphi code to some existing c. There are too many lengthy files (12 .c and 4 .h) for me to snip, and my C is horribly rusty, but I'll try.

For example, I have a file funcs.h:

#ifndef _FUNCS_H
#ifndef _FUNCS_H

#ifdef __cplusplus
extern "C" {
#endif

#include "New_Type.h"  // custom variable used in funcs.h
#include "Optional.h"  // optional set of more functions

typedef struct {
    int a1[4];
    double b1[10];

    // Computed if optional functions are requested
    double c1[10];
    int d1[4];
} func1;

typedef struct {
    new_type c2, d2;
} func2;
}
#endif
#endif

and files func1.c and func2.c do some mathematical manipulation (mostly linear algebra) of the above variables. My immediate questions are:

  1. Do I need multiple delphi files, much like there are multiple C headers?
  2. What do the delphi files' "skeletons" look like (premable, function calls)?
  3. What is {$LINKLIB C}, cdecl, and CALLBACK? Their common in other question/answers I've seen

Maybe I need to change my search/question, but I'm honestly not sure how to properly ask this. I don't need a specific answer, honestly I'd prefer if someone could point me to some links (heck a book: I'll be using this language in the future), I'd really appreciate it.

Thanks in advance for all the help.

1
1) depends on what you prefer, personally, I keep files small so that they are easy to read and follow. 2) don't really get this one 3) cdecl is calling convetion, you need to specify that to the compiler if you're calling a function from within a C dll for example, when calling a windows os function, you use stdcall in stead of cdecl, callback is just a pointer to a function, delphi/pascal forces you to specify the type(number of args and their types) of the function so that it leaves little room for error. hope this helps - user497849
(2) For example, I have uses System.Utils; at the top of the file (before each record function. Should there be other things (one file I saw had interface and unit in the code)? (3) Thanks, makes sense. - Kendra Lynne
The Delphi Language Guide in the documentation has a good explanation of how programs and units work, as well as what the unit structure is, and there are tons of examples in the VCL source (in your Delphi installation folder, in the Source\RTL and Source\VCL subfolders). Basically, what goes in the C .h file goes in the interface section, and what goes in the .c file goes in the implementation section. Whether you need multiple files or not is too broad to answer here based on the info you provided. - Ken White
You ask what you need, but you did not state what you are trying to do. - David Heffernan
Sorry about that, I deleted that sentece while I was editing and didn't realize. - Kendra Lynne

1 Answers

3
votes

Starting with #2: In Delphi, both the header and the implementation go in the same file. So here's a basic skeleton of a class showing where your header stuff (.h) and implementation stuff (.c) will fit into the structure of a unit/file in Delphi.

unit Unit1;

interface
  uses // List of header dependencies goes here...
  // Stuff from the .h file will go here
implementation
  uses // List of implementation dependencies goes here...
  // Stuff from the .c file will go here
end.

Back to #1: It's not strictly necessary to have a 1:1 mapping of your C header files to Delphi files, but if that was a good level of granularity per file in C, it's probably going to work out similarly in Delphi. Unless you have a good reason to change it, I'd leave them mapped at one C header file to one Delphi file.

About.com has a pretty detailed section on Delphi development, the page, for example, on working with units could be a good starting point on learning about the structure of a Delphi file. I also find myself using DelphiBasics as a reference site a lot (though it's more aimed at methods than structures). And definitely do not discount the official documentation on Embarcadero's website. Their Language Guide section is practically a textbook on learning Delphi, and is sufficiently detailed to get the fundamentals of the language.

And then as far as #3: This could easily be several separate full questions on stack overflow if you want more depth. But in general, it sounds like you're looking at code for calling c code directly from Delphi. CDecl is one of the calling conventions (the one that happens to match c...) which specifies which order parameters are passed to methods. Read more about it in Embarcadero's documentation. $LINKLIB is used to link to a library (in this case the C library, which you would do if you're calling c code), and callback is roughly equivalent to a function pointer in c.

From the overall sound of your third sub-question, I'm guessing you've been reading up on how to use C code in a Delphi project, without having to re-write the C code into Pascal/Delphi syntax, linking from delphi code to some existing c library you don't want to re-write or convert. If that's your ultimate goal, to just link to your C library without rewriting it, this article on using C in FreePascal may be of good help. For the purposes of linking to C code, the differences between FreePascal and Delphi, both variants of Pascal, are going to be relatively negligible). Basically, you have to re-write or convert the c header into Pascal syntax so that Delphi knows what functions are in your C library, so you can call them. Dr. Bob has a good detailed page about using C dlls in Delphi if you're looking for more info about converting header files. Amongst other useful information about how type names match, there is an example on that page of automated tools that exist for converting c header files to delphi headers. It may be easier to use an automated tool to convert your header to delphi syntax, if your goal is just to call or utilize your existing c code from a Delphi application without fully porting the entire code-library to Delphi.

And for the sake of example, your header from your question, converted through Dr. Bob's HeadConverter tool, gives output like this: (the actual output is longer and includes code for loading your c code as a dll and some comments as well)

unit FILE1;

interface
uses
  Windows;

{$INCLUDE "New_Type.h"}
{$INCLUDE "Optional.h"}

type
  func1 = record
    a1: Array[0..4-1] of Integer;
    b1: Array[0..10-1] of Double;
    c1: Array[0..10-1] of Double;
    d1: Array[0..4-1] of Integer;
  end {func1};

type
  func2 = record
    c2, d2: NEW_TYPE;
  end {func2};

{...}

implementation
   {...}
end.