0

I have a DLL that was provided by a 3rd party company and when called from Delphi 2007, it worked perfectly fine. The following code is a sample of how the DLL was used in Delphi 2007:

Procedure XC_eXpressLink(hHandle: Hwnd; Parameters: pChar; Result: pChar); stdcall; external 'XCClient.dll';

Here is how the procedure was called:

procedure TForm1.Button1Click(Sender: TObject);
  var Result: array[0..2000] of char;
  sParams: String;
begin
  sParams := RemoveCRLF(memoParameters.Text);  //Remove TMemo CR/LF
  XC_eXpressLink(Handle, pChar(sParams), Result);
  memoResults.Text := String(Result);
end;

I'm not sure what the DLL was compiled in, but I'm assuming it is expecting ansi and not unicode. After converting the code to ansi in Delphi XE5, the code is now as follows:

Procedure XC_eXpressLink(hHandle: Hwnd; Parameters: pAnsiChar; Result: pAnsiChar); stdcall; external 'XCClient.dll';

and

procedure TForm1.Button1Click(Sender: TObject);
  var Result: array[0..2000] of Ansichar;
  sParams: AnsiString;
begin
  sParams := RemoveCRLF(memoParameters.Text);  //Remove TMemo CR/LF
  XC_eXpressLink(Handle, pAnsiChar(sParams), Result);
  memoResults.Text := AnsiString(Result);
end;

memoParameters is a TMemo on the form which provides the parameters for the dll procedure. The RemoveCRLF is a function that removes any carriage returns and line feeds from memoParameters. MemoResults is another TMemo on the form that provides the return results of the dll procedure.

I'm getting access violations when the changed code is run in Delphi XE5. Since I changed all the parameters to use ansi, shouldn't the dll be getting the same parameter format as before? Am I doing something wrong? Will I be able to get this older compiled DLL to work in Delphi XE5?

RRUZ
  • 134,889
  • 20
  • 356
  • 483
Ron Swingler
  • 49
  • 1
  • 5
  • That looks fine. Is that really all the code. And how do you know 2000 characters is enough. – David Heffernan Aug 11 '16 at 21:43
  • The company that provided the DLL, gave a sample Delphi app which showed how to call their DLL. They were the ones that defined it at 2000 characters. They also provided an instruction manual that states, "The Result variable buffer must be pre-allocated to a minimum of 2000 bytes before calling the function." – Ron Swingler Aug 11 '16 at 22:02
  • The shown Ansi-converted code is technically correct, there is nothing wrong in it that should be causing an AccessViolation **IF** 1) the DLL is not overflowing the buffer, and 2) the buffer output is always null-terminated. On the other hand, this is not the first time that an AccessVioation has been reported related to using `XC_eXpressLink()` in XE5 (see [this](http://www.codenewsfast.com/cnf/thread/1606749003/permalink.thr-ng1909q22754) and [this](http://www.devsuperpage.com/search/Articles.aspx?G=2&ArtID=91383)). What does the *actual* AV error say? Did you try debugging it yet? – Remy Lebeau Aug 12 '16 at 00:42
  • @RemyLebeau Thanks for the info. I didn't realize someone else had the same problem. After the dll procedure is called, the 3rd party form for entering credit card info pops up. Then AV's are occurring when the mouse is passed over any of the entry fields on the credit card form. The AV error is "Access violation at address 6948540B. Read of address 6948540B." Also, as mentioned in your link and my comments above, the 3rd party requests a pre-allocated variable buffer of a minimum of 2000 bytes. I have tried increasing the amount but still results in the same AV errors. – Ron Swingler Aug 12 '16 at 16:37
  • @RonSwingler then the problem is inside the DLL itself. Contact the DLL vendor for help. Or step into the DLL machine code with the debugger. Maybe it is sending a weird message to your HWND that is not being handled correctly. Or maybe it depends on CPU flags that are not being set correctly. The DLL does deal with money values, so maybe there is a floating point incompatibility. It is a little odd that the AV is caused by a code address trying to read from its own address. That might imply an error in a dynamically allocated code stub/proxy. – Remy Lebeau Aug 12 '16 at 17:36
  • @RemyLebeau I will give the vendor a try. As a side note, as Wayne mentioned in one of your links, when passing a 0 Handle, the AV's are almost completely resolved. But in certain areas some AV's still occur. Not sure if that really helps or is a clue to solving this issue. Thanks and I really appreciate you help. – Ron Swingler Aug 12 '16 at 18:02
  • There could be an issue with memory management if the DLL is written in Delphi (or C++ Builder) and uses ShareMem. This is just a thought, I have no experience with this kind of situation (I have always avoided using ShareMem and also tried to discourage others to use it.) – dummzeuch Aug 19 '16 at 07:41

1 Answers1

0

I contacted the company, OpenEdge, which supplies the dll for X-Charge (for credit card integration). To resolve the problem, the Handle must have a value of 0 and you have to add /IGNOREHANDLEPARAMETER to the parameters list that is sent to the dll. Note, this parameter will only work with the full version XC8.1.1.6.exe installation or later.

procedure TForm1.Button1Click(Sender: TObject);
  var Result: array[0..2000] of Ansichar;
  sParams: AnsiString;
begin
  sParams := RemoveCRLF(memoParameters.Text);  //Remove TMemo CR/LF
  XC_eXpressLink(0, pAnsiChar(sParams), Result);
  memoResults.Text := AnsiString(Result);
end;
Ron Swingler
  • 49
  • 1
  • 5