www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Help with wininet.dll

reply "Bob W" <nospam aol.com> writes:
Tried to link a console program with wininet.dll, but to no avail. After 
several attempts to get it going, I finally have to ask people with some 
experience to post me a recipe how to get the linker to accept the fact that 
I want for example to call the InternetOpen() function in this Windows DLL. 
So far I have tried extern (Windows), export, implib /system and implib w/o 
the /system in various combinations, but that stubbon linker keeps telling 
me that functions I'd like to use cannot be found. The MSDN library web page 
was hinting that the functions I am interested in are available through 
wininet.lib (which I don't have), but I figured that wininet.dll might do 
the trick, since everything I want to use seems to be in there. Actually - 
not quite: Instead of InternetOpen they have packed InternetOpenA and 
InternetOpenW in the DLL. I have no idea what this is supposed to mean, and 
yes, I have tried to rename my function to InternetOpenA, but the linker 
keeps complaining (unable to find or unable to export).

Thanks in advance for further info!

P.S.:  Lcc-Win32 has automatically built import libraries and I have used 
the above mentioned function without problems (in C, but not inD). Of course 
the lcc library format is incompatible with the D linker, otherwise I've 
probably had a chance to get this working. 
Jan 23 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 24 Jan 2005 03:15:20 +1100, Bob W <nospam aol.com> wrote:
 Tried to link a console program with wininet.dll, but to no avail. After
 several attempts to get it going, I finally have to ask people with some
 experience to post me a recipe how to get the linker to accept the fact  
 that
 I want for example to call the InternetOpen() function in this Windows  
 DLL.
 So far I have tried extern (Windows), export, implib /system and implib  
 w/o
 the /system in various combinations, but that stubbon linker keeps  
 telling
 me that functions I'd like to use cannot be found. The MSDN library web  
 page
 was hinting that the functions I am interested in are available through
 wininet.lib (which I don't have), but I figured that wininet.dll might do
 the trick, since everything I want to use seems to be in there. Actually  
 -
 not quite: Instead of InternetOpen they have packed InternetOpenA and
 InternetOpenW in the DLL. I have no idea what this is supposed to mean,  
 and
 yes, I have tried to rename my function to InternetOpenA, but the linker
 keeps complaining (unable to find or unable to export).

 Thanks in advance for further info!

 P.S.:  Lcc-Win32 has automatically built import libraries and I have used
 the above mentioned function without problems (in C, but not inD). Of  
 course
 the lcc library format is incompatible with the D linker, otherwise I've
 probably had a chance to get this working.

I could be wrong, but, I don't think you can link with a DLL. Instead you load the library and get the address of the function you want, then using that address call the function. There is support in phobos for this, in the std.loader module. I've never used it myself but I have used the functions it calls: LoadLibrary GetProcAddress At a glance you'd do something like: # import std.c.windows.windows; # import std.loader; # # typedef void* HINTERNET; # # static DWORD INTERNET_OPEN_TYPE_PRECONFIG = 0; # static DWORD INTERNET_OPEN_TYPE_DIRECT = 1; # static DWORD INTERNET_OPEN_TYPE_PROXY = 3; # static DWORD INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY = 4; # # typedef HINTERNET function( # char* lpszAgent, # DWORD dwAccessType, # char* lpszProxyName, # char* lpszProxyBypass, # DWORD dwFlags # ) InternetOpenDef; # # void main() { # InternetOpenDef InternetOpen; # HINTERNET h; # HXModule m; # # ExeModule_Init(); # m = ExeModule_Load("wininet.dll"); # InternetOpen = cast(InternetOpenDef) ExeModule_GetSymbol(m,"InternetOpenA"); # h = InternetOpen("bob",INTERNET_OPEN_TYPE_DIRECT,null,null,0); # printf("InternetOpen returned (0x%08x)\n",h); # ExeModule_Uninit(); # } Regan
Jan 23 2005
parent reply "Bob W" <nospam aol.com> writes:
Thanks for your info, looked good at first.

Unfortunately I am geting
"Error: Access Violation"
after InternetOpen() was called.

I am even not sure whether InternetOpenA()
is compatible with InternetOpen() or not.



 I could be wrong, but, I don't think you can link with a DLL.

 Instead you load the library and get the address of the function you want, 
 then using that address call the function.

 There is support in phobos for this, in the std.loader module. I've never 
 used it myself but I have used the functions it calls:

 LoadLibrary
 GetProcAddress

 At a glance you'd do something like:

 # import std.c.windows.windows;
 # import std.loader;
 #
 # typedef void* HINTERNET;
 #
 # static DWORD INTERNET_OPEN_TYPE_PRECONFIG                    = 0;
 # static DWORD INTERNET_OPEN_TYPE_DIRECT                       = 1;
 # static DWORD INTERNET_OPEN_TYPE_PROXY                        = 3;
 # static DWORD INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  = 4;
 #
 # typedef HINTERNET function(
 #     char* lpszAgent,
 #     DWORD dwAccessType,
 #     char* lpszProxyName,
 #     char* lpszProxyBypass,
 #     DWORD dwFlags
 # ) InternetOpenDef;
 #
 # void main() {
 # InternetOpenDef InternetOpen;
 # HINTERNET h;
 # HXModule m;
 #
 # ExeModule_Init();
 # m = ExeModule_Load("wininet.dll");
 # InternetOpen = cast(InternetOpenDef) 
 ExeModule_GetSymbol(m,"InternetOpenA");
 # h = InternetOpen("bob",INTERNET_OPEN_TYPE_DIRECT,null,null,0);
 # printf("InternetOpen returned (0x%08x)\n",h);
 # ExeModule_Uninit();
 # }

 Regan 

Jan 24 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 25 Jan 2005 02:08:08 +1100, Bob W <nospam aol.com> wrote:
 Thanks for your info, looked good at first.

I saw your "no more help reqd" post but I figured I'd reply to this anyway, perhaps you can elaborate on what exactly was wrong and needed changing so that if another person has the same problem they will find your post and solve it.
 Unfortunately I am geting
 "Error: Access Violation"
 after InternetOpen() was called.

 I am even not sure whether InternetOpenA()
 is compatible with InternetOpen() or not.

IIRC there is no such function called "InternetOpen" exported from the DLL. Instead there are 2 functions "InternetOpenA" and "InternetOpenW" the A and W stand for ASCII and WIDE (IIRC). The same is true for a lot of windows functions, as you'll see if you look in dmd/src/phobos/std/c/windows/windows.d eg. DeleteFileA DeleteFileW When you call "DeleteFile" in your C/C++ program you're actually using a define that has been configured to either DeleteFileA or DeleteFileW based on whether you're doing a UNICODE build or not. (someone correct me if I've got any of this wrong)
 I could be wrong, but, I don't think you can link with a DLL.

 Instead you load the library and get the address of the function you  
 want,
 then using that address call the function.

 There is support in phobos for this, in the std.loader module. I've  
 never
 used it myself but I have used the functions it calls:

 LoadLibrary
 GetProcAddress

 At a glance you'd do something like:

 # import std.c.windows.windows;
 # import std.loader;
 #
 # typedef void* HINTERNET;
 #
 # static DWORD INTERNET_OPEN_TYPE_PRECONFIG                    = 0;
 # static DWORD INTERNET_OPEN_TYPE_DIRECT                       = 1;
 # static DWORD INTERNET_OPEN_TYPE_PROXY                        = 3;
 # static DWORD INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  = 4;
 #
 # typedef HINTERNET function(
 #     char* lpszAgent,
 #     DWORD dwAccessType,
 #     char* lpszProxyName,
 #     char* lpszProxyBypass,
 #     DWORD dwFlags
 # ) InternetOpenDef;
 #
 # void main() {
 # InternetOpenDef InternetOpen;
 # HINTERNET h;
 # HXModule m;
 #
 # ExeModule_Init();
 # m = ExeModule_Load("wininet.dll");
 # InternetOpen = cast(InternetOpenDef)
 ExeModule_GetSymbol(m,"InternetOpenA");
 # h = InternetOpen("bob",INTERNET_OPEN_TYPE_DIRECT,null,null,0);
 # printf("InternetOpen returned (0x%08x)\n",h);
 # ExeModule_Uninit();
 # }

 Regan


Jan 24 2005
parent reply "Bob W" <nospam aol.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message 
news:opsk4lkgt823k2f5 ally...
 On Tue, 25 Jan 2005 02:08:08 +1100, Bob W <nospam aol.com> wrote:
 Thanks for your info, looked good at first.

I saw your "no more help reqd" post but I figured I'd reply to this anyway, perhaps you can elaborate on what exactly was wrong and needed changing so that if another person has the same problem they will find your post and solve it.

"Exactly" is difficult because the problem, bug or whatever does the following: After calling the InternetOpenA function, the resulting pointer address can be displayed via printf or writef as suggested by your example. Calling InternetOpenA itself does not create problems at that point, but when main() exits the access violation is displayed. So InternetOpenA is causing some instability in D, which I am unable to pinpoint, except that I have removed any code past the troublespot and the problem stayed.
 Unfortunately I am geting
 "Error: Access Violation"
 after InternetOpen() was called.

 I am even not sure whether InternetOpenA()
 is compatible with InternetOpen() or not.

IIRC there is no such function called "InternetOpen" exported from the DLL. Instead there are 2 functions "InternetOpenA" and "InternetOpenW" the A and W stand for ASCII and WIDE (IIRC). The same is true for a lot of windows functions, as you'll see if you look in dmd/src/phobos/std/c/windows/windows.d eg. DeleteFileA DeleteFileW When you call "DeleteFile" in your C/C++ program you're actually using a define that has been configured to either DeleteFileA or DeleteFileW based on whether you're doing a UNICODE build or not. (someone correct me if I've got any of this wrong)

I am certain that your assumption is correct, thanks for your hints.
 I could be wrong, but, I don't think you can link with a DLL.

 Instead you load the library and get the address of the function you 
 want,
 then using that address call the function.

 There is support in phobos for this, in the std.loader module. I've 
 never
 used it myself but I have used the functions it calls:

 LoadLibrary
 GetProcAddress

 At a glance you'd do something like:

 # import std.c.windows.windows;
 # import std.loader;
 #
 # typedef void* HINTERNET;
 #
 # static DWORD INTERNET_OPEN_TYPE_PRECONFIG                    = 0;
 # static DWORD INTERNET_OPEN_TYPE_DIRECT                       = 1;
 # static DWORD INTERNET_OPEN_TYPE_PROXY                        = 3;
 # static DWORD INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  = 4;
 #
 # typedef HINTERNET function(
 #     char* lpszAgent,
 #     DWORD dwAccessType,
 #     char* lpszProxyName,
 #     char* lpszProxyBypass,
 #     DWORD dwFlags
 # ) InternetOpenDef;
 #
 # void main() {
 # InternetOpenDef InternetOpen;
 # HINTERNET h;
 # HXModule m;
 #
 # ExeModule_Init();
 # m = ExeModule_Load("wininet.dll");
 # InternetOpen = cast(InternetOpenDef)
 ExeModule_GetSymbol(m,"InternetOpenA");
 # h = InternetOpen("bob",INTERNET_OPEN_TYPE_DIRECT,null,null,0);
 # printf("InternetOpen returned (0x%08x)\n",h);
 # ExeModule_Uninit();
 # }

 Regan



Jan 24 2005
parent reply James McComb <ned jamesmccomb.id.au> writes:
Bob W wrote:

 After calling the InternetOpenA function, the resulting pointer
 address can be displayed via printf or writef as suggested by
 your example. Calling InternetOpenA itself does not create
 problems at that point, but when main() exits the access
 violation is displayed. So InternetOpenA is causing some
 instability in D, which I am unable to pinpoint, except that
 I have removed any code past the troublespot and the problem
 stayed.

For every "Open" function in the Windows API, there is a corresponding "Close" function that needs to be called. Are you calling InternetCloseHandle before exiting main()? James McComb
Jan 24 2005
parent "Bob W" <nospam aol.com> writes:
Of course I've actually started with a test program calling
Open and Close functions. That is where the access violation
has shown up first. Then I've tried various combinations with
equivalent results.

I could not tell whether calling the Open function or calling
any function through "std.loader" is the real problem,
because I wanted a working solution rather than playing
around to nail down a bug.

As mentioned, I have already found a different approach
to call these functions, so I won't pursue the "std.loader"
method again. Furthermore  "std.loader" was not mentioned
in the official Phobos web page - such things make me
usually suspicious.   ; )




"James McComb" <ned jamesmccomb.id.au> wrote in message 
news:ct474f$2vq6$1 digitaldaemon.com...
 Bob W wrote:

 After calling the InternetOpenA function, the resulting pointer
 address can be displayed via printf or writef as suggested by
 your example. Calling InternetOpenA itself does not create
 problems at that point, but when main() exits the access
 violation is displayed. So InternetOpenA is causing some
 instability in D, which I am unable to pinpoint, except that
 I have removed any code past the troublespot and the problem
 stayed.

For every "Open" function in the Windows API, there is a corresponding "Close" function that needs to be called. Are you calling InternetCloseHandle before exiting main()? James McComb

Jan 25 2005
prev sibling parent "Bob W" <nospam aol.com> writes:
Got it going:

- Needed to rename functions to be compatible with DLL.
- Def. file for libimp also needed some adaptation, in addition
   to that CODE & DATA directives can be omitted.
- Found some useful info on dmc web pages (not dmd pages).
Jan 24 2005