Delphi RSS Resources, Delphi Components, Delphi Sites, Articles, Dynamic XML Feeds, Tutorials, Sources
 
 
 
Google
 
Web delphirss.com
| Server-Scripts.com | Informations for JAVA | Informations for PHP | SEO Web Links | Borland Delphi
 

DLL

Callback example
Floating point trouble in DLLs
VER.DLL functions
Uses in DLLs
CARDS.DLL


Callback example

Question

I have to call a function in my main prg from a DLL, and the only way to do
this seems to be to use callbacks. Does anyone have a source example of how
this can be done in Delphi?

Answer

A:
This is how I'm having a C++ DLL callback a Delphi procedure:

In Delphi:
----------
interface

var
  callBackProc : TFarProc;

procedure delphiProc (const x: Pchar); export;
procedure setupDLL (p: pointer);

implementation

procedure setupDLL (p: Pointer);  external 'MYDLL';

procedure delphiProc (const x: Pchar); { this is the procedure called back }
begin
   ...
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
   ...
   callBackProc := makeProcInstance(@delphiProc, gInstance);
   setupDLL (callBackProc);
   ...
end;

procedure TForm1.FormDestroy (Sender: TObject);
begin
   ...
   freeProcInstance (callBackProc);
   ...
end;


In the C++ DLL:
---------------
   static void CALLBACK (*saveProc)(char*);

   void FAR _export pascal setupDLL (void CALLBACK (*func)(char*))
   {
      saveProc = func;
   }

then, to call the Delphi proc from the C++ DLL, use:

  (*saveProc)(msg);  // where msg is a char*

You don't have to do the makeProcInstance or freeProcInstance where I've
shown them, you just need to make sure you do the makeProcInstance and setup
calls before the callback is used, and the freeProcInstance after the last
time the callback is used.

If your DLL is in Delphi, the code would be similar, except I don't remember
how to call a procedure in Delphi via a pointer to that procedure.

If your DLL is not in Delphi, make sure you keep aware of string/pchar
consistency.

A:
The syntax is the same. In the main prg you just add the keyword EXPORT to
each function you need to export, just as if in a .DLL. Near the end of the
.DPR file, just before the BEGIN keyword that defines the start of the main
program you add a section called EXPORTS where you list again the routine(s)
you want to make available for callbacks. The not so obvious but very important
step you must do is to compile the main prg with the compiler smart callbacks
option off. This is very important, as the routines in the main prg must be
able to access their own data.

Floating point trouble in DLLs

Question

Got problem using Floating point numbers in DLLs.
I wrote a DLL using C++. The function in C++ needed a float variable.
I send the Single variable in Delphi to the DLL Function.
I got a GPF error stating Invalid Opcode. Anyone can help?

Answer

A:
If you wrote both the DLL and the Delphi side, do not return floating point
values as the function return value. Instead, use a var parameter (a pointer or
reference parameter in C++)
to return values.

I am assuming that your DLL is compiled by M$ VC++. The reason
is that Borland and M$ use different ways of returning a floating point value.
Borland's C++ and Delphi might use the same way (in the Math Coprocessor stack)
but I'm not sure.

So, if you work with procedures instead of functions you should be OK.

BTW, do not use single or float precision. They may be changed by the
compiler. Use doubles.

VER.DLL functions

Question

Does anybody have any experience using the version-checking functions in
VER.DLL? The online help for this is clear as mud (to me at least). I'm
writing a simple setup routine (I have to write my own, because it does few
things I can't find in any of the available shareware installers) and need
to do version checking on a few shared DLLs.

Answer

A:
This isn't exactly what you are looking for, but it might be useful. I use
the version information in my "About" boxes, code is below. You may not have
to use the StringFileInfo block at all for simple version checking, but
instead get the info out of the root block (see the TVS_FIXEDFILEINFO
structure in the API help).

procedure TAboutBox.FormCreate(Sender: TObject);
var
  VIHandle : LongInt;
  VSize : LongInt;
  VData : Pointer;
  VVers : Pointer;
  Len : Word;
  FileName : String;

const
  Prefix = '\StringFileInfo\040904E4\'; { Prejudiced to U.S. character set, if
                                          I remember right }   

  function GetVerValue(Value : String) : String;
    var
      ItemName : String;

    begin
      ItemName := Prefix + Value + chr(0);
      Result := '';
      If VerQueryValue(VData,@ItemName[1],VVers,Len)
        Then
          If Len > 0
            Then
              Begin
                If Len > 255
                  Then
                    Len := 255; { "Truncate" any long strings }
                Move(VVers^, Result[1], Len);
                Result[0] := Chr(Len);
              End;
    end;

begin
  FileName := Application.EXEName + chr(0);
  VSize := GetFileVersionInfoSize(@FileName[1], VIHandle);
  If VIHandle <> 0
    Then
      Begin
        GetMem(VData, VSize);
        Try
          If GetFileVersionInfo(@FileName[1], VIHandle, VSize, VData)
            Then
              Begin
                { At this point, I grab values from the StringFileInfo block,
                  but you could just as easily get values from the root 
                  block using VerQueryValue }

                ProductName.Caption := GetVerValue('ProductName');
                Version.Caption := GetVerValue('ProductVersion');
                Copyright.Caption := GetVerValue('LegalCopyright');
                Comments.Caption := GetVerValue('FileDescription');
              End;
        Finally
          FreeMem(VData, VSize);
        End;
      End;
end;

Uses in DLLs

Question

If I keep 'uses Forms;' in a formless DLL project, the compiled DLL file is
about 140kb.  If I delete 'Forms' from the uses clause, it doesn't compile.
If I delete the whole uses clause, it compiles happily to about 2kb,
but occasionally the IDE complains about the lack of a uses clause.
Is it safe to have no uses clause?
The DLL at the moment is only an experiment, but I hope to use a DLL in my
program.

Answer

A:
You're not really following the proper syntax for a DLL.  Here's
the way to do it right:

You need at least two files-- the library file and the source
code file:

Library file:  mylib.dpr

  library MyLib;

  uses
    MyCode in 'MYCODE.PAS';

  exports
    MyFunc index 1;

  begin
  end.

Source file:  mycode.pas

  unit MyCode;

  interface

  function MyFunc( MyParam: string ): string; export;

  implementation

  function MyFunc( MyParam: string ): string;

  begin
  Result := 'This was just an example!';
  end;

  end.

Follow this format and you can't miss...  taken (loosely) from
the Delphi Developer's Guide from Borland Press/Sams Publishing.

CARDS.DLL

Question

I understand that every copy of windows comes with CARDS.DLL that
contains the cards as drawn in Microsoft card games.  Does anybody
know function names of functions in this DLL ?

Answer

I'm afraid I don't know how the functions work and all, but I can give you
the names and ordinal numbers of the functions in the DLL:

        0               Card Display Technology
        5               CDTANIMATE
        4               CDTTERM
        3               CDTDRAWEXT
        2               CDTDRAW
        1               CDTINIT

A:
Thanks to Heath Ian Hunnicutt (heathh@cco.caltech.edu) for disassembling
CARDS.DLL and coming up with the basis for this documentation.

 cards.h

#include "crd.h"

/*
 *  cdtInit: Initializes the cards module
 *
 *  pdxCard: receives the width of the card
 *  pdyCard: receives the height of the card
 *  returns: success or failure
 */
BOOL FAR PASCAL cdtInit(int FAR *pdxCard, int FAR *pdyCard);

/*
 *  cdtDrawExt: Draw a card with specified extents (size)
 *
 *  x, y:    location to draw the card
 *  dx,dy:   size to be drawn
 *  cd:      card to be drawn
 *  mode:    transfer mode
 *  returns: success or failure
 */
BOOL FAR PASCAL cdtDrawExt(HDC hdc, int x, int y, int dx, int dy,=20
					int cd, int mode, DWORD rgbBgnd);

/*
 *  cdtDraw: Draw a card
 *
 *  x, y:    location to draw the card
 *  cd:      card to be drawn
 *  mode:    transfer mode
 *  returns: success or failure
 */
BOOL FAR PASCAL cdtDraw(HDC hdc, int x, int y, int cd, int mode,
				   DWORD rgbBgnd);

/*
 *  cdtTerm: terminates and cleans up the cards module

 */
void FAR PASCAL cdtTerm();


 cdt.h

#define CLOADMAX 5

/* Command ids */
#define IDACLUBS	 1
#define ID2CLUBS	 2
#define ID3CLUBS	 3
#define ID4CLUBS	 4
#define ID5CLUBS	 5
#define ID6CLUBS	 6
#define ID7CLUBS	 7
#define ID8CLUBS	 8
#define ID9CLUBS	 9
#define IDTCLUBS	 10
#define IDJCLUBS	 11
#define IDQCLUBS	 12
#define IDKCLUBS	 13

#define IDADIAMONDS	 14
#define ID2DIAMONDS	 15
#define ID3DIAMONDS	 16
#define ID4DIAMONDS	 17
#define ID5DIAMONDS	 18
#define ID6DIAMONDS	 19
#define ID7DIAMONDS	 20
#define ID8DIAMONDS	 21
#define ID9DIAMONDS	 22
#define IDTDIAMONDS	 23
#define IDJDIAMONDS	 24
#define IDQDIAMONDS	 25

#define IDKDIAMONDS	 26

#define IDAHEARTS	 27
#define ID2HEARTS	 28
#define ID3HEARTS	 29
#define ID4HEARTS	 30
#define ID5HEARTS	 31
#define ID6HEARTS	 32
#define ID7HEARTS	 33
#define ID8HEARTS	 34
#define ID9HEARTS	 35
#define IDTHEARTS	 36
#define IDJHEARTS	 37
#define IDQHEARTS	 38
#define IDKHEARTS	 39

#define IDASPADES	 40
#define ID2SPADES	 41
#define ID3SPADES	 42
#define ID4SPADES	 43
#define ID5SPADES	 44
#define ID6SPADES	 45
#define ID7SPADES	 46
#define ID8SPADES	 47
#define ID9SPADES	 48
#define IDTSPADES	 49
#define IDJSPADES	 50
#define IDQSPADES	 51
#define IDKSPADES	 52

#define IDGHOST	53

#define IDFACEDOWN1 	54
#define IDFACEDOWN2 	55
#define IDFACEDOWN3 	56
#define IDFACEDOWN4 	57
#define IDFACEDOWN5 	58
#define IDFACEDOWN6 	59
#define IDFACEDOWN7 	60
#define IDFACEDOWN8 	61
#define IDFACEDOWN9 	62
#define IDFACEDOWN10 63
#define IDFACEDOWN11 64
#define IDFACEDOWN12	65

#define IDFACEDOWNFIRST IDFACEDOWN1
#define IDFACEDOWNLAST IDFACEDOWN12

#define IDX 67
#define IDO 68
#define IDMAX IDDECK

/* internal IDs for animation */
#define IDASLIME1 678
#define IDASLIME2 679
#define IDAKASTL1 680
#define IDAFLIPE1 681
#define IDAFLIPE2 682
#define IDABROBOT1 683
#define IDABROBOT2 684

/* Red non-face card frame */
#define IDFRAME 999

#define FACEUP		0
#define FACEDOWN	1   /* for compatibility with old apps, use

 IDFACEDOWNFIRST..IDFACEDOWNLAST */
#define HILITE		2
#define GHOST		3
#define REMOVE		4
#define INVISIBLEGHOST 5
#define DECKX		6
#define DECKO		7


 crd.h

#include "cdt.h"

typedef int CD;

// CaRD struct, this is what a card be
typedef struct _crd {
	unsigned cd  : 15;		// card # (1..52)
	unsigned fUp : 1;		// is this card up/down
	PT pt;				// upper-left corner of card
	} CRD;

/* WARNING: Order of su's is assumed */
#define suClub 0
#define suDiamond 1
#define suHeart 2
#define suSpade 3
#define suMax 4
#define suFirst suClub

#define raAce 0
#define raDeuce 1
#define raTres 2
#define raFour 3
#define raFive 4
#define raSix 5
#define raSeven 6
#define raEight 7
#define raNine 8
#define raTen 9
#define raJack 10
#define raQueen 11

#define raKing 12
#define raMax 13
#define raNil 15
#define raFirst raAce

typedef int RA;
typedef int SU;

#define cdNil 0x3c

#define cIDFACEDOWN (IDFACEDOWNLAST-IDFACEDOWNFIRST+1)

#define SuFromCd(cd) ((cd)&0x03)
#define RaFromCd(cd) ((cd)>>2)
#define Cd(ra, su) (((ra)<<2)|(su))









© DelphiRSS.com. All Rights Reserved.