www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - bindings/win32, RAS, error 632

reply "Leonid Krashenko" <jetbird gmail.com> writes:
Hello!

I have a question about using bindings/win32, RAS.

I've
1. compiled win32.lib (-version=WindowsXP),
2. used "implib rasapi32.lib rasapi32.def" with written by hand  
rasapi32.def with following content (linkdef (don't know why) can't find  
any of that symbols):
Code:
LIBRARY RASAPI32
DESCRIPTION 'rasapi32.dll'
EXETYPE NT

EXPORTS
_D5win323ras20RasGetConnectStatusAFT5win323ras8HRASCONNPS5win323r
s14RASCONNSTATUSAZk  
= RasGetConnectStatusA
_D5win323ras18RasGetErrorStringAFkPakZk = RasGetErrorStringA
_D5win323ras15RasEnumEntriesAFPaPaPS5win323ras13RASENTRYNAMEAPkPkZk =  
RasEnumEntriesA



3. compiled the following code:
Code:
PhoneBookEntries getPhoneBookEntries() {
     auto entries = new PhoneBookEntries;

     RASENTRYNAME[100] buf;
     buf.ptr.dwSize = RASENTRYNAME.sizeof;
     uint entriesNum, length = buf.length*RASENTRYNAME.sizeof;

// THIS IS IMPORTANT err VARIABLE
     auto err = RasEnumEntries(null, null, buf.ptr, &length, &entriesNum);

// ....

     return entries;
}



with cmd: Code:

dmd -c -ofmain.obj main.d -version=WindowsXP
dmd -c -ofrasdial.obj rasdial.d -version=WindowsXP
dmd main.obj rasdial.obj -ofdialer rasapi32.lib win32.lib  
-version=WindowsXP



4. and always get 'err' variable equal to 632, "ERROR_INVALID_STRUCTURE"  
(see http://msdn.microsoft.com/en-us/library/aa377380(VS.85).aspx for  
RasEnumEntries function details),

BUT the analogous DELPHI code works perfectly:
Code:
procedure getPhoneBookEntries(list: TStrings);
var
   BuffSize          : Integer;
   Entries           : Integer;
   Entry             : Array[1..MaxEntries] of TRasEntryName;
   X,Result_         : Integer;
begin
   list.Clear;
   Entry[1].dwSize:=SizeOf(TRasEntryName);
   BuffSize:=SizeOf(TRasEntryName)*MaxEntries;
   Result_:=RasEnumEntries(nil, nil,  Entry[1], BuffSize, Entries);


...

There is something I do wrong here... but what?
Apr 09 2009
next sibling parent "Leonid Krashenko" <Leonid.Krashenko gmail.com> writes:
On Thu, 09 Apr 2009 22:02:12 +0400, Leonid Krashenko <jetbird gmail.com>  
wrote:

 Hello!

 I have a question about using bindings/win32, RAS.

 I've
 1. compiled win32.lib (-version=WindowsXP),
 2. used "implib rasapi32.lib rasapi32.def" with written by hand  
 rasapi32.def with following content (linkdef (don't know why) can't find  
 any of that symbols):
 Code:
 LIBRARY RASAPI32
 DESCRIPTION 'rasapi32.dll'
 EXETYPE NT

 EXPORTS
 _D5win323ras20RasGetConnectStatusAFT5win323ras8HRASCONNPS5win323r
s14RASCONNSTATUSAZk  
 = RasGetConnectStatusA
 _D5win323ras18RasGetErrorStringAFkPakZk = RasGetErrorStringA
 _D5win323ras15RasEnumEntriesAFPaPaPS5win323ras13RASENTRYNAMEAPkPkZk =  
 RasEnumEntriesA



 3. compiled the following code:
 Code:
 PhoneBookEntries getPhoneBookEntries() {
      auto entries = new PhoneBookEntries;

      RASENTRYNAME[100] buf;
      buf.ptr.dwSize = RASENTRYNAME.sizeof;
      uint entriesNum, length = buf.length*RASENTRYNAME.sizeof;

 // THIS IS IMPORTANT err VARIABLE
      auto err = RasEnumEntries(null, null, buf.ptr, &length,  
 &entriesNum);

 // ....

      return entries;
 }



 with cmd: Code:

 dmd -c -ofmain.obj main.d -version=WindowsXP
 dmd -c -ofrasdial.obj rasdial.d -version=WindowsXP
 dmd main.obj rasdial.obj -ofdialer rasapi32.lib win32.lib  
 -version=WindowsXP



 4. and always get 'err' variable equal to 632, "ERROR_INVALID_STRUCTURE"  
 (see http://msdn.microsoft.com/en-us/library/aa377380(VS.85).aspx for  
 RasEnumEntries function details),

 BUT the analogous DELPHI code works perfectly:
 Code:
 procedure getPhoneBookEntries(list: TStrings);
 var
    BuffSize          : Integer;
    Entries           : Integer;
    Entry             : Array[1..MaxEntries] of TRasEntryName;
    X,Result_         : Integer;
 begin
    list.Clear;
    Entry[1].dwSize:=SizeOf(TRasEntryName);
    BuffSize:=SizeOf(TRasEntryName)*MaxEntries;
    Result_:=RasEnumEntries(nil, nil,  Entry[1], BuffSize, Entries);


 ...

 There is something I do wrong here... but what?

I've mistaken, not ERROR_INVALID_STRUCTURE, but ERROR_INVALID_SIZE (which means "Incorrect structure size", http://msdn.microsoft.com/en-us/library/bb530704(VS.85).aspx)
Apr 09 2009
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Leonid Krashenko wrote:
<snip>
     RASENTRYNAME[100] buf;
     buf.ptr.dwSize = RASENTRYNAME.sizeof;
     uint entriesNum, length = buf.length*RASENTRYNAME.sizeof;

What value are you actually getting for RASENTRYNAME.sizeof? And does buf.sizeof give the same value as buf.length*RASENTRYNAME.sizeof, as it should? <snip>
 BUT the analogous DELPHI code works perfectly:
 Code:
 procedure getPhoneBookEntries(list: TStrings);
 var
   BuffSize          : Integer;
   Entries           : Integer;
   Entry             : Array[1..MaxEntries] of TRasEntryName;
   X,Result_         : Integer;
 begin
   list.Clear;
   Entry[1].dwSize:=SizeOf(TRasEntryName);
   BuffSize:=SizeOf(TRasEntryName)*MaxEntries;

Again, what values are you getting? Stewart.
Apr 09 2009
next sibling parent reply "Leonid Krashenko" <Leonid.Krashenko gmail.com> writes:
On Fri, 10 Apr 2009 01:57:16 +0400, Stewart Gordon <smjg_1998 yahoo.com>  
wrote:

 Leonid Krashenko wrote:
 <snip>
     RASENTRYNAME[100] buf;
     buf.ptr.dwSize = RASENTRYNAME.sizeof;
     uint entriesNum, length = buf.length*RASENTRYNAME.sizeof;

What value are you actually getting for RASENTRYNAME.sizeof? And does buf.sizeof give the same value as buf.length*RASENTRYNAME.sizeof, as it should?

Yes, it does; RASENTRYNAME size = 532 WINVER = 0x501 (-version=WindowsXP)
 <snip>
 BUT the analogous DELPHI code works perfectly:
 Code:
 procedure getPhoneBookEntries(list: TStrings);
 var
   BuffSize          : Integer;
   Entries           : Integer;
   Entry             : Array[1..MaxEntries] of TRasEntryName;
   X,Result_         : Integer;
 begin
   list.Clear;
   Entry[1].dwSize:=SizeOf(TRasEntryName);
   BuffSize:=SizeOf(TRasEntryName)*MaxEntries;

Again, what values are you getting?

Delphi: SizeOf(TRasEntryName) = 264 bufsize = 26400 MinGW C++ variant of this program has WINVER = 0x400, entry size = 264 (works fine too).
 Stewart.

Apr 09 2009
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Leonid Krashenko wrote:
<snip>
 What value are you actually getting for RASENTRYNAME.sizeof?

 And does buf.sizeof give the same value as 
 buf.length*RASENTRYNAME.sizeof, as it should?

Yes, it does; RASENTRYNAME size = 532 WINVER = 0x501 (-version=WindowsXP)

Which agrees with my calculation. <snip>
 Delphi:
 SizeOf(TRasEntryName) = 264
 bufsize = 26400
 
 MinGW C++ variant of this program has WINVER = 0x400, entry size = 264 
 (works fine too).

You're comparing apples and oranges somewhat here. Delphi and MinGW with version set to 0x400, D bindings with version set to 0x501. If you try comparing like with like, _then_ what works and what doesn't? That said, on re-reading your original post, I can guess what you're doing wrong: trying to work around the missing extern (C) attributes in ras.d instead of fixing them. And consequently, merely renaming the functions and not actually fixing the calling convention. I got it to link by fixing this error, and then.... ---------- C:\Documents and Settings\Stewart\My Documents\D>type rastest.d import win32.ras, std.stdio; void main() { RASENTRYNAME[100] buf; buf.ptr.dwSize = RASENTRYNAME.sizeof; uint entriesNum, length = buf.sizeof; writefln("structure size: ", RASENTRYNAME.sizeof); auto err = RasEnumEntries(null, null, buf.ptr, &length, &entriesNum); writefln("RasEnumEntries returned: ", err); } C:\Documents and Settings\Stewart\My Documents\D>dmd rastest.d win32\ras.d C:\Documents and Settings\Stewart\My Documents\D>rastest structure size: 264 RasEnumEntries returned: 0 C:\Documents and Settings\Stewart\My Documents\D>dmd -version=WindowsXP rastest.d win32\ras.d C:\Documents and Settings\Stewart\My Documents\D>rastest structure size: 532 RasEnumEntries returned: 0 ---------- FTM what version of Windows are you trying it on? This is under XP (I'm away from my usual computer for a week and a bit). Stewart.
Apr 10 2009
prev sibling parent "Leonid Krashenko" <Leonid.Krashenko gmail.com> writes:
 That said, on re-reading your original post, I can guess what you're  
 doing wrong: trying to work around the missing extern (C) attributes in  
 ras.d instead of fixing them.  And consequently, merely renaming the  
 functions and not actually fixing the calling convention.  I got it to  
 link by fixing this error, and then....

It works now! I have Win XP. It works, but not with extern(C) (although it links and runs - but runs with errors if you, for example, try to print names of entries, - looks like there are memory collisions or something of that). Look at the output (extern(C)): OPTLINK (R) for Win32 Release 8.00.1 Copyright (C) Digital Mars 1989-2004 All rights reserved. rasapi32.lib Warning 2: File Not Found rasapi32.lib dialer.obj(dialer) Error 42: Symbol Undefined _RasGetConnectStatusA dialer.obj(dialer) Error 42: Symbol Undefined _RasGetErrorStringA dialer.obj(dialer) Error 42: Symbol Undefined _RasEnumEntriesA and of the extern(Windows): --- errorlevel 3 OPTLINK (R) for Win32 Release 8.00.1 Copyright (C) Digital Mars 1989-2004 All rights reserved. rasapi32.lib Warning 2: File Not Found rasapi32.lib dialer.obj(dialer) Error 42: Symbol Undefined _RasGetConnectStatusA 8 dialer.obj(dialer) Error 42: Symbol Undefined _RasGetErrorStringA 12 dialer.obj(dialer) Error 42: Symbol Undefined _RasEnumEntriesA 20 --- errorlevel 3 P.S. Thank you for explanation! (I've thought there can't be any error in win32/ras.d (last commit was about 3 years ago!), and was trying to find it elsewhere :)
Apr 10 2009
prev sibling parent Kagamin <spam here.lot> writes:
Leonid Krashenko Wrote:

 2. used "implib rasapi32.lib rasapi32.def" with written by hand  
 rasapi32.def with following content (linkdef (don't know why) can't find  
 any of that symbols):

you should use coffimplib
Apr 10 2009