Board index » delphi » Calling 'C' DLL's from Delphi 2.0

Calling 'C' DLL's from Delphi 2.0

I posted to this newsgroup about two weeks ago with this query, thanks
to everyone that replied, but I am _still_ having trouble :(

To refresh your memory, I am trying to call the following function:

        void nspdRealFft ( double * samples, int order, int flags)

In Delphi, the function call is declared as:

        procedure nspdRealFft (var s: pointer; o, f : integer);
                    stdcall; external 'nsppx.dll' ;

I kept getting Access violation exceptions, or other run time errors.

I compared, using Turbo De{*word*81} (TD32), the calls for the function from
both Delphi and C++.  Results are as follows:

        For a call from the C++ program, the stack is

        0000 0001       - the value of the 'flags' parameter
        0000 0009       - the value of the 'order' parameter
        0073 edf4       - the starting address of the first double
        #### ####       - the old IP (didn't write it down)

        For a call from the Delphi program, the stack is

        0000 0001       - the value of the 'flags' parameter
        0000 0009       - the value of the 'order' parameter
        0042 4664       - the starting address of the first double
        #### ####       - the old IP (didn't write it down)

This was using the delphi program fragment :

        type
                darray = array [1..514] of double;
        var
                fftarray : darray;
                p : pointer;

        procedure nspdRealFft (var s: pointer; o, f : integer);
                stdcall; external 'nsppx.dll' ;

        procedure TForm1.Button1Click(Sender: TObject);
        begin
                p := addr(fftarray);
                nspdRealFft( pointer(p^), 9, 1);
        end;

As you can see, the parameters passed on the stack are in the correct
order, and I checked that the address passed for the 'samples' parameter
is actually the first element of the array in question, for both the C++
and Delphi versions.

What happens now is that the Delphi program creates another Access
Violation exception, at an address far outside my memory space!  This
exception is raised within the DLL.  The source code for the DLL is
unavailable.

I am now uncertain as to how I am going to proceed from here.

Any sort of help is more than welcome.  If anyone wants a copy of my
code or the executables, please mail me in return.

Thanks in advance,

Mark Harrington
ma...@ozramp.net.au

To email me, please remove the _SPAM_ME_NOT_ field from my email address

 

Re:Calling 'C' DLL's from Delphi 2.0


Quote
Mark Harrington wrote:

> I posted to this newsgroup about two weeks ago with this query, thanks
> to everyone that replied, but I am _still_ having trouble :(

> To refresh your memory, I am trying to call the following function:

>         void nspdRealFft ( double * samples, int order, int flags)

> In Delphi, the function call is declared as:

>         procedure nspdRealFft (var s: pointer; o, f : integer);
>                     stdcall; external 'nsppx.dll' ;

> I kept getting Access violation exceptions, or other run time errors.

         procedure nspdRealFft (s: pointer; o, f : integer);
                     stdcall; external 'nsppx.dll' ;

'var s:pointer' would be passed as a pointer to a pointer.

Use just 'S:POINTER'

--
Need a custom component? Late on a project? Could use an util?
DOS Device driver? A VxD? NT drivers or services? Applications of any
kind?
Low rates, fast delivery!

When responding to news postings, please CC a copy to my email address.
Thanks.
Erik Sperling Johansen <e...@info-pro.no>

Re:Calling 'C' DLL's from Delphi 2.0


I'm not sure that it may help you, but I had the same problem.
I wanted to call a C DLL from a Delphi 2.0 application, and I
had the same "Access violation" errors that you met. I couldn't
fix the problem for the moment, but I found a "trick" to bypass it ...
In fact, the problem starts with the second parameter (and there
is also a problem of integer size which may be different in Delphi
and in C (use Smallint to ensure a 16 bit value)).

May be this is stupid, but it actually works fine ! Just pass ONE
parameter, like a structure pointer ! Here is what I did :

// Define a structure and a pointer on this structure

type
  PExample = ^Example;
  Example = record
    szName:  array[0..30] of Char;
    szTest: array[0..200] of Char;
    dDay,dMonth,dYear: double;
    ...
end;

// Declare the DLL's function so that Delphi load it at startup
// Note the use of pascal type for a C++ DLL, and the explicite
// name of the DLL with extension, so that it works with NT4 ...

procedure DelphiTEST(lp: pointer); pascal;
  external 'BALICIEL.DLL' name 'DelphiTEST';
...
procedure CalcTest(Fen: TForm);
var p: PExample;
begin
  // Assume that an object was created (using New ...)
  // and its handle stored in the Tag property of the form
  p := PExample(Fen.Tag);
  p^.szName := 'Test';
  p^.szTest := 'One more test';
  dDay := 1;
  dMonth := 1;
  dYear := 2000;
  DelphiTEST(p);
  ...
end;

Hope this may help you ...

--
o?o?,,?o?oo?  Jean-Michel CAMBOT   ?oo?o?,,?o?o
o?o?,,?o?oo?  balic...@cge-ol.XXX.fr   ?oo?o?,,?o?o
... Please remove XXX from the address to answer ...
Site BALICIEL French : http://www.cge-ol.fr/baliciel/  ;o)
Site BALICIEL English : http://www.cge-ol.fr/baliciel/welcome1.htm  ;o)

Mark Harrington <markh@_SPAM_ME_NOT_ozramp.net.au> a crit dans l'article
<3314D64F.5C68@_SPAM_ME_NOT_ozramp.net.au>...
...

Quote
> What happens now is that the Delphi program creates another Access
> Violation exception, at an address far outside my memory space!  This
> exception is raised within the DLL.  The source code for the DLL is
> unavailable.

...

Re:Calling 'C' DLL's from Delphi 2.0


void nspdRealFft ( double * samples, int order, int flags)

procedure nspdRealFft(var s: Double; o, f: Integer); stdcall;
  external 'blahblah....'

double * samples is a pointer to a double.

var s: double is the same thing.

Whenever you (in general) see a C dec like  -- type *f --, always
convert using -- var f: type --

--
Michael Heacock         "Hail hail the lucky ones,
Praxis Technical Group   I refer to those in love"
Nanaimo BC Canada                -- Eddie Vedder

Re:Calling 'C' DLL's from Delphi 2.0


void nspdRealFft ( double * samples, int order, int flags)

procedure nspdRealFft(var s: Double; o, f: Integer); stdcall;
  external 'blahblah....'

double * samples is a pointer to a double.

var s: double is the same thing.

Whenever you (in general) see a C dec like  -- type *f --, always
convert using -- var f: type --

--
Michael Heacock         "Hail hail the lucky ones,
Praxis Technical Group   I refer to those in love"
Nanaimo BC Canada                -- Eddie Vedder

Re:Calling 'C' DLL's from Delphi 2.0


Quote
Mike Heacock wrote:

> void nspdRealFft ( double * samples, int order, int flags)

> procedure nspdRealFft(var s: Double; o, f: Integer); stdcall;
>   external 'blahblah....'

> double * samples is a pointer to a double.

> var s: double is the same thing.

> Whenever you (in general) see a C dec like  -- type *f --, always
> convert using -- var f: type --

While this usually works, it isn't always safe.  Falls over with
booleans for example.  Since C doesn't really have types as such,
just different sizes of things, I usually find it's best to map
"type *f" to "f: pointer", make sure that the pointer is a pointer
to something of the right size for C to deal with, bearing in mind
that 2 bytes is a sensible minimum size for passing anything to a C
routine, and cross my fingers and legs.
--
Matt
        m...@dovecot.demon.co.uk
  http://www.setanta.demon.co.uk

Re:Calling 'C' DLL's from Delphi 2.0


Quote
Mark Harrington (markh@_SPAM_ME_NOT_ozramp.net.au) wrote:

: I posted to this newsgroup about two weeks ago with this query, thanks
: to everyone that replied, but I am _still_ having trouble :(
:
: To refresh your memory, I am trying to call the following function:
:
:       void nspdRealFft ( double * samples, int order, int flags)
:
: In Delphi, the function call is declared as:
:      
:       procedure nspdRealFft (var s: pointer; o, f : integer);
:                   stdcall; external 'nsppx.dll' ;

Just a small question:
        Why if the first parameter in the pascal declaration var s: pointer.
Shouldn't it be something like:
        type
                PDouble = ^Double;
        var d: PDouble.

:  <snip>

                                      - Chirag Dalal

----------------------------------------------------------
 M. Tech., Department of Computer Science and Engineering
 Indian Institute of Technology, Powai, Bombay.
----------------------------------------------------------
 E-Mail Address: da...@cse.iitb.ernet.in

 For Cool Delphi Components See
 Home page: http://www.cse.iitb.ernet.in/~dalal/delphi
----------------------------------------------------------

Other Threads