user415496
user415496

Reputation: 11

Call dll function

I have to acces a c written dll function, prototyped as:

#include "extcode.h"
#pragma pack(push)
#pragma pack(1)

#ifdef __cplusplus
extern "C" {
#endif

void __stdcall PSA_Send_BO(char hostname[], char BO_NumberIn[], 
    char BO_NumberOut[], int16_t *Status, char Error_text[], int32_t *Error_code, 
    int32_t *length_BO_NumberOut, int32_t *length_error_text);

long __cdecl LVDLLStatus(char *errStr, int errStrLen, void *module);

#ifdef __cplusplus
} // extern "C"
#endif

#pragma pack(pop)

My Delphi code:

procedure Aaa(HostNaam: PChar; BO_To: PChar; BO_From: PChar; ErrorText: PChar;
              var OutputLength: LongInt;  var ErrorLength: LongInt; 
              var ErrorNumber: Longint
              ) ; far; stdcall; external 'aaa.dll'


{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
  BO_From, ErrorText: Array[0..999] of Char;
  ErrorLength, BoLength, ErrorNumber: LongInt;
begin
  Aaa(PChar(edtHostName.Text), PChar(edtBoNumber.Text), BO_From, ErrorText, BoLength, ErrorLength, ErrorNumber);

  Label1.Caption := 'BO_From = ' + BO_From ;
  Label2.Caption := 'BoLength = ' + IntToStr(BoLength);
  Label3.Caption := 'ErrorText = ' + ErrorText; 
  Label4.Caption := 'ErrorLength = ' + IntToStr(ErrorLength);  
  Label5.Caption := 'ErrorNumber = ' + IntToStr(ErrorNumber);
end;

When I run this example, the returned strings BO_From and ErrorText are empty, all other returned parameters are OK.

When I comment one of the lines out where I do the display of the returned parameters, the strings are displayed well! Stepping into the code with the debugger has similar effect. Copying all returned parameters before displaying them has no effect. The length of the returned strings is far below the declared size.

Does someone has any clue?

Thanks in advance for any help,

Cock

Upvotes: 1

Views: 752

Answers (3)

Dan Bartlett
Dan Bartlett

Reputation: 826

As Sertac Akyuz mentioned, you have a missing Status parameter, and since stdcall parameters are passed right-to-left (http://docwiki.embarcadero.com/RADStudio/en/Procedures_and_Functions#Calling_Conventions), any parameters declared before this missing parameter will be corrupted.

If you want the code to function on Delphi 2009+ you should also convert PChar => PAnsiChar, and Char => AnsiChar, since SizeOf(Char)=2 on Delphi 2009+.

The "far" directive is also obsolete.

procedure Aaa(HostNaam: PAnsiChar; BO_To: PAnsiChar; BO_From: PAnsiChar;
              var Status: SmallInt; ErrorText: PAnsiChar; 
              var OutputLength: LongInt;  var ErrorLength: LongInt;  
              var ErrorNumber: Longint 
              ) ; stdcall; external 'aaa.dll';

Upvotes: 1

Sertac Akyuz
Sertac Akyuz

Reputation: 54822

You've got a missing var Status: Smallint in the declaration of procedure Aaa.

Upvotes: 1

Don Dickinson
Don Dickinson

Reputation: 6258

Without seeing the details of the dll, it is hard to say exactly what is going on. One thing, though ...

Do you need to set ErrorLength and BOLength? Usually on calls like this these are filled in with the size of the buffer on the call. That allows the dll to avoid any kind of buffer overrun. So try, setting them to 999 before making the call.

Upvotes: 0

Related Questions