Board index » delphi » Problems Loading a DLL

Problems Loading a DLL

Hi,

I'm working with Delphi (2.0) and right now I'm stuck in a very stupid
problem. The problem deals with the loading of a DLL. This DLL is built
with Microsoft C++ 1.52.

It is impossible to load this DLL and I tried it in two ways:

1) First, (Proof #1 below) is the implicit way and when I execute
   it from the Delphi environment the returned is:
   "De{*word*81} Kernel Error. Error Code: 1."

2) Second, (Proof #2) is the explicit way. When I execute the routine
   "LoadLibrary(...)" it returns always zero. This error means:
   "System was out of memory, executable file was corrupt, or
   relocations were invalid".

For your information, the DLL in question (TEKDCI.DLL) contains some
functions to control an image acquisition board.

I will be very grateful if you could help me in this trouble.
Thanks you in advance and don't hesitate to contact me for
further information or anything else.

Sincerely yours

Jesus Galceran <galce...@esaii.upc.es>

-------------------------------------------------------------------
   Proof #1 (Implicit Load)
-------------------------------------------------------------------

   unit Init2;

   interface

   uses
     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls, Buttons;

   type
     TForm1 = class(TForm)
       Button1: TButton;
       procedure Button1Click(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
     end;

   var
     Form1: TForm1;
     BoardID : Integer;

   implementation

   {$R *.DFM}

   function TEK_Init: Integer; far pascal; external 'tekdci.dll';

   //
   //  Loading & Calling the DLL
   //
   procedure TForm1.Button1Click(Sender: TObject);
   begin
      BoardID:=TEK_Init;
      if BoardID > 0 then ShowMessage ('Board Initialized')
      else ShowMessage ('Initialization Failure');
   end;

   end.

-------------------------------------------------------------------
   Proof #2 (Explicit Load)
-------------------------------------------------------------------

   unit Init3;

   interface

   uses
     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls, Buttons;

   type
     TInit = function: Integer;

     TForm1 = class(TForm)
       Button1: TButton;
       procedure Button1Click(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
     end;

   var
     Form1  : TForm1;
     hTekDCI: THandle;
     Init   : TInit;
     FuncPtr: TFarProc;
     hDLL   : THandle;
     BoardID: Integer;

   implementation

   {$R *.DFM}

   //
   //  Loading & Calling the DLL
   //
   procedure TForm1.Button1Click(Sender: TObject);
   begin
      hTekDCI:=LoadLibrary('tekdci.DLL');
      if hTekDCI < HINSTANCE_ERROR then   // If there are any problem...
      begin
         ShowMessage ('      Error loading DLL      ');
         exit;
      end
      else begin
         FuncPtr:=GetProcAddress(hTekDCI, 'TEK_Init');
         @Init:=FuncPtr;
         if @Init <> nil then
         begin
            BoardID:=Init;
            if BoardID > 0 then ShowMessage ('Board Initialized')
            else ShowMessage ('Initialization Failure');
         end
         else ShowMessage ('Can not Load Routine');
      end;
      FuncPtr:=nil;
      FreeLibrary(hTekDCI);
   end;

   end.

-------------------------------------------------------------------
   Notes perhaps important:
-------------------------------------------------------------------

- In file DLL.H (included by the manufacturer) there is the following
  definition:
     #define DLLCALL  __far __pascal __export

- Next, there is the TEK_Init() definition

    int DLLCALL TEK_Init()

    * Parameters:
      -------------
         None

    * Return Value:
      -------------
         The function returns <0 to indicate failure. If initializa-
         tion is successful it returns the Board ID.
         The return ID can be 0, 1 or 2.

         Error Code Definition: 1: No hardware installed
                                2: Fail to initial hardware
                                3: INI file not found
                                4: DMA vxd not installed
                                5: No DCI Driver
                                6: Create DCI Primary Fail
                                7: Lock Memory Error

    * Description:
      -------------
         This function initializes the board using the information
         specified in the INI file.

-----------------------------------------------------------------------
  Jesus Galceran           |    The human mind ordinarily operates at  
  galce...@esaii.upc.es    |    only ten percent of its capacity...  
  Lab Docent - ESAII       |    The rest is overhead for the Operating
  Edifici U - FIB - UPC    |    System ;-)
-----------------------------------------------------------------------

 

Re:Problems Loading a DLL


perhaps the problem is in calling functions in a
16bit dll from a 32bit program.

(as i recall, VC++ 1.x was 16 bit?)

hope this helps
julian

Quote
Jesus Galceran wrote:

> Hi,

> I'm working with Delphi (2.0) and right now I'm stuck in a very stupid
> problem. The problem deals with the loading of a DLL. This DLL is built
> with Microsoft C++ 1.52.

> It is impossible to load this DLL and I tried it in two ways:

> 1) First, (Proof #1 below) is the implicit way and when I execute
>    it from the Delphi environment the returned is:
>    "De{*word*81} Kernel Error. Error Code: 1."

> 2) Second, (Proof #2) is the explicit way. When I execute the routine
>    "LoadLibrary(...)" it returns always zero. This error means:
>    "System was out of memory, executable file was corrupt, or
>    relocations were invalid".

> For your information, the DLL in question (TEKDCI.DLL) contains some
> functions to control an image acquisition board.

> I will be very grateful if you could help me in this trouble.
> Thanks you in advance and don't hesitate to contact me for
> further information or anything else.

> Sincerely yours

> Jesus Galceran <galce...@esaii.upc.es>

> -------------------------------------------------------------------
>    Proof #1 (Implicit Load)
> -------------------------------------------------------------------

>    unit Init2;

>    interface

>    uses
>      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
>      Dialogs, StdCtrls, Buttons;

>    type
>      TForm1 = class(TForm)
>        Button1: TButton;
>        procedure Button1Click(Sender: TObject);
>      private
>        { Private declarations }
>      public
>        { Public declarations }
>      end;

>    var
>      Form1: TForm1;
>      BoardID : Integer;

>    implementation

>    {$R *.DFM}

>    function TEK_Init: Integer; far pascal; external 'tekdci.dll';

>    //
>    //  Loading & Calling the DLL
>    //
>    procedure TForm1.Button1Click(Sender: TObject);
>    begin
>       BoardID:=TEK_Init;
>       if BoardID > 0 then ShowMessage ('Board Initialized')
>       else ShowMessage ('Initialization Failure');
>    end;

>    end.

> -------------------------------------------------------------------
>    Proof #2 (Explicit Load)
> -------------------------------------------------------------------

>    unit Init3;

>    interface

>    uses
>      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
>      Dialogs, StdCtrls, Buttons;

>    type
>      TInit = function: Integer;

>      TForm1 = class(TForm)
>        Button1: TButton;
>        procedure Button1Click(Sender: TObject);
>      private
>        { Private declarations }
>      public
>        { Public declarations }
>      end;

>    var
>      Form1  : TForm1;
>      hTekDCI: THandle;
>      Init   : TInit;
>      FuncPtr: TFarProc;
>      hDLL   : THandle;
>      BoardID: Integer;

>    implementation

>    {$R *.DFM}

>    //
>    //  Loading & Calling the DLL
>    //
>    procedure TForm1.Button1Click(Sender: TObject);
>    begin
>       hTekDCI:=LoadLibrary('tekdci.DLL');
>       if hTekDCI < HINSTANCE_ERROR then   // If there are any problem...
>       begin
>          ShowMessage ('      Error loading DLL      ');
>          exit;
>       end
>       else begin
>          FuncPtr:=GetProcAddress(hTekDCI, 'TEK_Init');
>          @Init:=FuncPtr;
>          if @Init <> nil then
>          begin
>             BoardID:=Init;
>             if BoardID > 0 then ShowMessage ('Board Initialized')
>             else ShowMessage ('Initialization Failure');
>          end
>          else ShowMessage ('Can not Load Routine');
>       end;
>       FuncPtr:=nil;
>       FreeLibrary(hTekDCI);
>    end;

>    end.

> -------------------------------------------------------------------
>    Notes perhaps important:
> -------------------------------------------------------------------

> - In file DLL.H (included by the manufacturer) there is the following
>   definition:
>      #define DLLCALL  __far __pascal __export

> - Next, there is the TEK_Init() definition

>     int DLLCALL TEK_Init()

>     * Parameters:
>       -------------
>          None

>     * Return Value:
>       -------------
>          The function returns <0 to indicate failure. If initializa-
>          tion is successful it returns the Board ID.
>          The return ID can be 0, 1 or 2.

>          Error Code Definition: 1: No hardware installed
>                                 2: Fail to initial hardware
>                                 3: INI file not found
>                                 4: DMA vxd not installed
>                                 5: No DCI Driver
>                                 6: Create DCI Primary Fail
>                                 7: Lock Memory Error

>     * Description:
>       -------------
>          This function initializes the board using the information
>          specified in the INI file.

> -----------------------------------------------------------------------
>   Jesus Galceran           |    The human mind ordinarily operates at
>   galce...@esaii.upc.es    |    only ten percent of its capacity...
>   Lab Docent - ESAII       |    The rest is overhead for the Operating
>   Edifici U - FIB - UPC    |    System ;-)
> -----------------------------------------------------------------------

Re:Problems Loading a DLL


If you try running your program outside of the development environment
you may get a better indication of the problem.  The "Kernel error" is
often due to a missing/not found DLL.  

In my (limited) experience, running the program from, say, explorer
usually gives me a better "error message", with which to track down and
fix the problem.

Hope this helps.

Tim Kelly

Re:Problems Loading a DLL


On Mon, 12 May 1997 14:00:11 -0700, Jesus Galceran

Quote
<galce...@esaii.upc.es> wrote:
>Hi,

>I'm working with Delphi (2.0) and right now I'm stuck in a very stupid
>problem. The problem deals with the loading of a DLL. This DLL is built
>with Microsoft C++ 1.52.

>It is impossible to load this DLL and I tried it in two ways:

I assume that your dll uses the C calling convention.  If so, try
putting the cdecl keyword in your function declaration like this:

function Foo; Integer; cdecl; external; "MyDll' etc...

Re:Problems Loading a DLL


On Mon, 12 May 1997 14:00:11 -0700, Jesus Galceran

Quote
<galce...@esaii.upc.es> wrote:
>Hi,

>I'm working with Delphi (2.0) and right now I'm stuck in a very stupid
>problem. The problem deals with the loading of a DLL. This DLL is built
>with Microsoft C++ 1.52.

Delphi 2.0 is 32-bit.  MSC++ 1.52 is 16-bit.  It's non-trivial to call
16-bit DLLs from 32-bit programs.  You will have much better luck if
you build the DLL as a 32-bit DLL; otherwise you have a lot of
low-level "thunking" work to do, and it will be very hard.
J. Merrill / Analytical Software Corp

Re:Problems Loading a DLL


On Thu, 15 May 1997 03:40:59 GMT, jmerr...@mnsinc.com (James Merrill)
wrote:

Quote
>On Mon, 12 May 1997 14:00:11 -0700, Jesus Galceran
><galce...@esaii.upc.es> wrote:

>>Hi,

>>I'm working with Delphi (2.0) and right now I'm stuck in a very stupid
>>problem. The problem deals with the loading of a DLL. This DLL is built
>>with Microsoft C++ 1.52.

>Delphi 2.0 is 32-bit.  MSC++ 1.52 is 16-bit.  It's non-trivial to call
>16-bit DLLs from 32-bit programs.  You will have much better luck if
>you build the DLL as a 32-bit DLL; otherwise you have a lot of
>low-level "thunking" work to do, and it will be very hard.
>J. Merrill / Analytical Software Corp

Yea boy...  I scanned the first part of his article and missed the
1.52 part.  You're absolutely right.  Unless he wants to hassle with
the Thunk compiler, just re-do the thing in 32 bits.

I posted a response about what it takes to do thunking.  I've had to
do it in the past, and don't recommend it to anyone :)

david sampson

dsamp...@atlanta.com

Other Threads