Thread overview
Help with wininet.dll
Jan 23, 2005
Bob W
Jan 24, 2005
Regan Heath
Jan 24, 2005
Bob W
Jan 24, 2005
Regan Heath
Jan 25, 2005
Bob W
Jan 25, 2005
James McComb
Jan 25, 2005
Bob W
No more help required, thanks
Jan 24, 2005
Bob W
January 23, 2005
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.


January 24, 2005
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
January 24, 2005
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


January 24, 2005
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).



January 24, 2005
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
>
>

January 25, 2005

"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
>>
>>


January 25, 2005
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
January 25, 2005
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