Problems accessing a C++ dll that needs a struct from D7

Posted on 2005-04-19
Medium Priority
Last Modified: 2010-04-05
The important .h stuff:

#define MAX_PATH 4096

#ifdef _WIN32
  #pragma pack (push, 1)
  #pragma pack(1)

typedef struct _INFO_FILE
  unsigned long   cbSize;
  char            Path[MAX_PATH];
  char            Mode[8];

typedef struct _INFO_BUFFER
  unsigned long   cbSize;
  void  *         Buffer;
  unsigned long   Size;

typedef struct _INFO_ITEM
  int             Type;
  int             ItemFormat;
    INFO_BUFFER   InfoBuffer;                
    INFO_FILE     InfoFile;

HRESULT WINAPI api_OpenItem                      (IN API_CLID clid, IN INFO_ITEM *info,OUT API_ITEM * item);

This is what I've come up with so far:

  MAX_PATH = 4096;

  PInfo_Buffer = ^TInfo_Buffer;
  TInfo_Buffer = record
    cbsize  : LongWord;
    Buffer  : Pointer;
    Size    : LongWord;

  PInfo_File = ^TInfo_File;
  TInfo_File = record
    cbsize  : LongWord;
    Path    : array[0..MAX_PATH - 1] of Char;
    Mode    : array[0..7] of Char;

  PInfo_Item = ^TInfo_Item;
  TInfo_Item = record
    ItemType   : Integer;
    ItemFormat : Integer;
    case Integer of
      0: (ItemBuffer : TInfo_Buffer);
      1: (ItemFile   : TInfo_File);

function api_OpenItem(
    API_CLID: THandle;      
    InfoItem: PInfo_Item;
    out API_ITEM: THandle    
  ): LongWord;
  stdcall; external 'api.dll';

  engine: THandle;
  item: THandle;

procedure TForm1.Button2Click(Sender: TObject);
  p: TInfo_Item;
  fn: String;                
  r: LongWord;
  fn := edtFileName.Text;
  p.ItemType := API_ITEM_FILE;
  p.ItemFormat := API_ITEM_FORMAT_OTHER;
  p.ItemFile.cbsize := SizeOf(TInfo_File);
  StrPCopy(p.ItemFile.Path, fn);
  StrPCopy(p.ItemFile.Mode, 'rb');
  r := api_OpenItem(engine, @p, item);
  if (r <> API_OK)
  then showmessage('ERROR: ' + inttostr(r))
  else showmessage('success');


The dll simply returns a generic error message. "engine" is assigned (successfully) in an earlier call. I've tried the records both packed and as you see it.

Any help would be greatly appreciated.
Question by:orbit1star
  • 4
  • 3
LVL 26

Expert Comment

by:Russell Libby
ID: 13818709

Just for future reference, the #pragma pack(1) is an indicator that "packed record" should be used on the record structs (though in this instance the structs are all DWORD aligned anyways).

Regarding the error though, it appears that engine is never assigned anything before being passed? Is this intentional, or should there be a call to allocate/init/whatever the engine before making the call to api_OpenItem? If not, then you should probably be passing zero to the engine param, or setting engine:=0, as Delphi does not initialize its variables (meaning engine will have whatever is currently in memory at that address).



Author Comment

ID: 13818752
Engine is assigned in an earlier function (I noted that at the bottom ;-) ). I'm pretty sure the engine value is valid - I can make another, different call and get results with the same engine parameter.
LVL 26

Expert Comment

by:Russell Libby
ID: 13818813

>"The dll simply returns a generic error message. "engine" is assigned (successfully) in an earlier call. I've tried the records both packed and as you see it.

Sorry, the wording made it sound like the error message was "engine is assigned..." Btw, what IS the actual message coming back? You might also try to define the api call as:

 PHandle = ^THandle;

function api_OpenItem(API_CLID: THandle; InfoItem: PInfo_Item; API_ITEM: PHandle): LongWord; stdcall; external 'api.dll';

and call it with

api_OpenItem(engine, @p, @item);


Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Author Comment

ID: 13818913
Ahh - one man's english is another man's bad english. ;-)

The generic error message it return is just that: API_ERR. It's the only constant with no details.

Doesn't the out qualifier work just as well? I used that to get the engine value earlier with no problem. (I just tried changing both to pointers as suggested to no avail)

I checked the "demo" code earlier, and I'm doing everything it is doing:

    INFO_ITEM fle;
    strcpy(fle.ItemData.InfoFile.Path, FileName);
    strcpy(fle.ItemData.InfoFile.Mode, "rb");

    api_OpenItem(Opt->clid, &fle, &item)

The demo app seems to work ok, so I can't blame the dll - yet. =\
LVL 26

Accepted Solution

Russell Libby earned 2000 total points
ID: 13819051

Yes, the qualifiers should be the same, but some API's allow null to be passed (and therein would lie the difference). It was just a shot...

Anyways, I checked all the structs, and they are the same size regardless of packed, so the problem does not appear to be there. The code you have appears to be the same as the demo..... as far as I can tell (though I don't see the defs for API_CLID or API_ITEM, so can't say for sure). And the file name you are passing is fully qualified as well?...

Other than that, it really is impossible to say without more to go on. Which leads to the next question...

Is this an open source library (something that someone else could check out)?



Author Comment

ID: 13819830

Ok, thanks for the help. I came here with the idea that the answer just might be that I'm doing everything right (at least as far as the structs, types, and conventions go). I guess my next step is to look into possible configuration issues. I also discovered a Debug mode call I'm going to try out.

It's not open source, unfortunately, and I've even obscured a few of the names of the function calls due to my NDA. Such is life.

Muchas gracias; answer accepted. :-)
LVL 26

Expert Comment

by:Russell Libby
ID: 13819952
Thanks, and sorry I could not help further with this...


Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses

862 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