Recent

Author Topic: Access Violation When Function Reaches END;  (Read 8083 times)

Weitentaaal

  • Hero Member
  • *****
  • Posts: 554
Access Violation When Function Reaches END;
« on: March 15, 2021, 08:01:22 am »
Hello Guys :)

My Problem:
I Call a External DLL and already had many Problems with String Conversations.
Now i Got this AV but it doesn't tell me much where the Error is.

Here my Code:
Code: Pascal  [Select][+][-]
  1.  
  2. //Def
  3. TZAJsonRequestBSTR = Function(sRequest : WideString): WideString; stdcall;
  4.  
  5. //Calling The DLL
  6. Function Call_ZAJsonRequestBSTR(sRequest : WideString): WideString;
  7. var
  8.    // Legt eine passende Variable (Datenfeld) für das DLL-Unterprogramm an
  9.    ZAJsonRequestBSTR : TZAJsonRequestBSTR;
  10.    // Legt einen Handle für den Handle der DLL an
  11.    LibHandle: THandle;
  12. begin
  13.    //Einbinden Der DLL
  14.    LibHandle := LoadLibrary(PChar('C:\DLLS\FANselect.dll'));
  15.    if(LibHandle <> 0)then begin
  16.       // Weisst der Variablen ZAJsonRequestBSTR die Adresse des Unterprogrammaufrufs zu
  17.       // 'ZAJsonRequestBSTR' aus der DLL FANSelect.dll zu.
  18.       Pointer(ZAJsonRequestBSTR) := GetProcAddress(LibHandle, 'ZAJsonRequestBSTR');
  19.  
  20.       // Prüft, ob eine gültige Adresse zurück gegeben wurde
  21.       if @ZAJsonRequestBSTR <> nil then begin
  22.          //Blackbox aufrufen
  23.          result := ZAJsonRequestBSTR(sRequest);
  24.       End;
  25.    End;
  26.  
  27.    // Freigabe des Arbeitsspeichers
  28.    ZAJsonRequestBSTR := nil;
  29.    FreeLibrary(LibHandle);
  30. end;
  31.  
  32.  
  33. //Calling in Code
  34. //Both Strings Here are WideStrings (because WideString Supports COM Memory of BSTR)
  35. JZaRueckgabe := DLLAufrufe.Call_ZAJsonRequestBSTR(JZa);
  36.      
  37.  

Hope u can help me.

Zvoni

  • Hero Member
  • *****
  • Posts: 3349
Re: Access Violation When Function Reaches END;
« Reply #1 on: March 15, 2021, 08:22:44 am »
WideString vs. PWideString?

Without seeing the Function-Prototype of the dll-function it's gazing into a crystal ball
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Weitentaaal

  • Hero Member
  • *****
  • Posts: 554
Re: Access Violation When Function Reaches END;
« Reply #2 on: March 15, 2021, 08:27:19 am »
There is the Problem .. i dont't Have the DLL Code  :-\

Tested With PWideString but got the Same Error.

The Calling Worked Fine in VB6, checked if i Have the Same input, wich i had. But no Output Somehow.
But Still why do i get Av when the Code reaches End; ? is it because of an empty String wich returns ?
« Last Edit: March 15, 2021, 08:47:41 am by Weitentaaal »

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 881
Re: Access Violation When Function Reaches END;
« Reply #3 on: March 15, 2021, 09:36:12 am »
Please provide initial VB6 declaration of this function. I guess, problem is caused by simple fact, that string is allocated by DLL's memory manager and FPC fails to deallocate it properly. BSTR is OLE string, allocated by SysAllocString. May be it should be represented as OleVariant? Is your application 32bit? Because VB6 is 32bit and therefore DLL should be 32bit too.
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

Weitentaaal

  • Hero Member
  • *****
  • Posts: 554
Re: Access Violation When Function Reaches END;
« Reply #4 on: March 15, 2021, 10:03:49 am »
VB6 Code :

Code: Pascal  [Select][+][-]
  1.      
  2.       //Definition    
  3.       Public Declare Function ZAJsonRequestBSTR Lib "C:\WGKBlck\Ziehl-Abegg\FANselect.dll" (ByVal sRequest As String) As String
  4.  
  5.       //Called like that
  6.       JZa = StrConv(JZa, vbUnicode)
  7.       JZa2 = StrConv(JZa2, vbUnicode)
  8.    
  9.       JZaRückgabe = StrConv(ZAJsonRequestBSTR(JZa), vbFromUnicode)
  10.  

Didn't Tested with OLE variant till now.

Application is 32 bit

Zvoni

  • Hero Member
  • *****
  • Posts: 3349
Re: Access Violation When Function Reaches END;
« Reply #5 on: March 15, 2021, 12:42:27 pm »
IIRC, in vb6 passing a String ByVal to an external dll is still passing the address to the String.
And a Returntype of string is probably still a pointer to the Resultstring
That's why i figured PWideString.
Have you tried both as PWideString? the Argument and the return-Type?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

PascalDragon

  • Hero Member
  • *****
  • Posts: 6381
  • Compiler Developer
Re: Access Violation When Function Reaches END;
« Reply #6 on: March 15, 2021, 01:04:34 pm »
Here my Code:

Two remarks (though both are probably not related to your problem):

- you need to use FreeLibrary only if LibHandle is not 0
- to check whether the function was loaded correctly you need to use ZAJsonRequestBSTR <> Nil (or Assigned(ZAJsonRequestBSTR)); using @ZAJsonRequestBSTR will check whether the variable itself has a valid address.

IIRC, in vb6 passing a String ByVal to an external dll is still passing the address to the String.
And a Returntype of string is probably still a pointer to the Resultstring
That's why i figured PWideString.
Have you tried both as PWideString? the Argument and the return-Type?

According to the manual (page 42) of the library the C(++) declaration for the functions is as follows:

Code: C  [Select][+][-]
  1. external “C” {
  2.   __declspec(dllimport)
  3.   const char* __stdcall ZAJsonRequestA(const char *szReq);
  4.  
  5.   __declspec(dllimport)
  6.   const wchar_t* __stdcall ZAJsonRequestW(const wchar_t *szReq);
  7.  
  8.   __declspec(dllimport)
  9.   const BSTR __stdcall ZAJsonRequestBSTR(BSTR sReq);
  10. }

So using WideString instead of PWideString is indeed correct.

Weitentaaal

  • Hero Member
  • *****
  • Posts: 554
Re: Access Violation When Function Reaches END;
« Reply #7 on: March 15, 2021, 01:15:09 pm »
Not Sure what i should do next but i bet the Problem is there because of the type.

The Function did the Job it had to in vb6 so there must be the Problem in the in and output, but i don't get it.

WideString Should be Supported by BSTR or am i wrong ?
So where else could this Call go wrong ?

I Will Test if its Working with pointers...

Thanks for ur Replys, i realy appreciate. :)
« Last Edit: March 15, 2021, 01:27:15 pm by Weitentaaal »

Zvoni

  • Hero Member
  • *****
  • Posts: 3349
Re: Access Violation When Function Reaches END;
« Reply #8 on: March 15, 2021, 02:19:59 pm »
Here my Code:

Two remarks (though both are probably not related to your problem):

- you need to use FreeLibrary only if LibHandle is not 0
- to check whether the function was loaded correctly you need to use ZAJsonRequestBSTR <> Nil (or Assigned(ZAJsonRequestBSTR)); using @ZAJsonRequestBSTR will check whether the variable itself has a valid address.

IIRC, in vb6 passing a String ByVal to an external dll is still passing the address to the String.
And a Returntype of string is probably still a pointer to the Resultstring
That's why i figured PWideString.
Have you tried both as PWideString? the Argument and the return-Type?

According to the manual (page 42) of the library the C(++) declaration for the functions is as follows:

Code: C  [Select][+][-]
  1. external “C” {
  2.   __declspec(dllimport)
  3.   const char* __stdcall ZAJsonRequestA(const char *szReq);
  4.  
  5.   __declspec(dllimport)
  6.   const wchar_t* __stdcall ZAJsonRequestW(const wchar_t *szReq);
  7.  
  8.   __declspec(dllimport)
  9.   const BSTR __stdcall ZAJsonRequestBSTR(BSTR sReq);
  10. }

So using WideString instead of PWideString is indeed correct.
Wait a sec.
Quote
A BSTR is a composite data type that consists of a length prefix, a data string, and a terminator. The following table describes these components.
Remarks
Item    Description
Length prefix    A four-byte integer that contains the number of bytes in the following data string. It appears immediately before the first character of the data string. This value does not include the terminator.
Data string    A string of Unicode characters. May contain multiple embedded null characters.
Terminator    A NULL (0x0000) WCHAR.
How does WideString handle that?

@Weitentaaal: Have you tried the ZAJsonRequestW-Function?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 881
Re: Access Violation When Function Reaches END;
« Reply #9 on: March 15, 2021, 02:35:21 pm »
How does WideString handle that?

@Weitentaaal: Have you tried the ZAJsonRequestW-Function?
Manual says, that WideString is right type for BSTR. But using ZAJsonRequestW is better idea.

I would also use asm debugger to find exact cause of this problem.
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

lucamar

  • Hero Member
  • *****
  • Posts: 4217
Re: Access Violation When Function Reaches END;
« Reply #10 on: March 15, 2021, 02:56:01 pm »
Wait a sec.
Quote
A BSTR is a composite data type that consists of a length prefix, a data string, and a terminator. The following table describes these components.
Remarks
Item    Description
Length prefix    A four-byte integer that contains the number of bytes in the following data string. It appears immediately before the first character of the data string. This value does not include the terminator.
Data string    A string of Unicode characters. May contain multiple embedded null characters.
Terminator    A NULL (0x0000) WCHAR.
How does WideString handle that?

Exactly like that; see the Programmer's Guide,  Memory Issues: WideStrings. It can't be otherwise since its main use is for COM interfaces.
« Last Edit: March 15, 2021, 02:58:05 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Weitentaaal

  • Hero Member
  • *****
  • Posts: 554
Re: Access Violation When Function Reaches END;
« Reply #11 on: March 15, 2021, 05:17:54 pm »
Finished work for Today but i will try it Tomorrow. Thank u all Guys for ur patience with me :D.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Access Violation When Function Reaches END;
« Reply #12 on: March 15, 2021, 05:39:08 pm »
Wait a sec.
Quote
A BSTR is a composite data type that consists of a length prefix, a data string, and a terminator. The following table describes these components.
Remarks
Item    Description
Length prefix    A four-byte integer that contains the number of bytes in the following data string. It appears immediately before the first character of the data string. This value does not include the terminator.
Data string    A string of Unicode characters. May contain multiple embedded null characters.
Terminator    A NULL (0x0000) WCHAR.
How does WideString handle that?

Exactly like that; see the Programmer's Guide,  Memory Issues: WideStrings. It can't be otherwise since its main use is for COM interfaces.
I see a difference, the length is in negative location offset. Am I right?

Edit:
If am right, the dll function is taking the first four byes of the WideString, that is the first two WideChars, as the wrong length of the string. For a string like: 'ABC', this would seem to the dll function as a string that is $00420041 bytes long, while in fact it is only 6 bytes long plus two terminating bytes
.
« Last Edit: March 15, 2021, 08:14:27 pm by engkin »

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 881
Re: Access Violation When Function Reaches END;
« Reply #13 on: March 15, 2021, 06:23:30 pm »
I see a difference, the length is in negative location offset. Am I right?

Edit:
If am right, the dll function is taking the first four byes of the WideString, that is the first two WideChars, as the wrong length of the string. For a string like: 'ABC', this would seem to the dll function as a string that is $00420041 bytes long, while in fact it is only 6 bytes long plus two terminating bytes.
Managed strings work exactly this way in Pascal - they have explicit length field and trailing null.
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Access Violation When Function Reaches END;
« Reply #14 on: March 15, 2021, 06:45:50 pm »
I see a difference, the length is in negative location offset. Am I right?

Edit:
If am right, the dll function is taking the first four byes of the WideString, that is the first two WideChars, as the wrong length of the string. For a string like: 'ABC', this would seem to the dll function as a string that is $00420041 bytes long, while in fact it is only 6 bytes long plus two terminating bytes.
Managed strings work exactly this way in Pascal - they have explicit length field and trailing null.

Not exactly,. The offset is negative, AND the value of length is the number of (Wide)Chars, instead of bytes. For WideString, that is 3 instead of 6 in the 'ABC' example.

WideString in not equivalent to BStr.

Edit:
Both, WideString and BStr, use negative offset for length. But the value is not the same.
« Last Edit: March 15, 2021, 08:09:39 pm by engkin »

 

TinyPortal © 2005-2018