With Irvine32.lib linked, and irvine32.inc included, I can invoke a few functions that VC originally does not support, such as Clrscr() or Gotoxy().
VC has never supported those functions.
So if I invoke Clrscr() somewhat, then the actual binary data for Clsscr() must be fired from some OS supported dlls such as ntdll.dll or kernel32.dll, both of which, however, clearly do not have it supported.
I Dumpbin-ed Irvine32.lib but I could not find the location from which that function is called.
How does Irvine32.lib magically make it available to call the unsupported functions I mentioned?
Thanks in advance.
The code for Irvine is available! If you looked at it you would see that Kip, used the following Win32 API calls to implement his versions:
Clrscr
GetConsoleScreenBufferInfo
WriteConsoleOutputCharacter
WriteConsoleOutputAttribute
SetConsoleCursorPosition
Gotoxy
SetConsoleCursorPosition
If you don't like his ways, you could always implement your own versions.
Related
I'm trying to load GetStagedPackageOrigin WinAPI dynamically using LoadLibrary and GetProcAddress so that my app could also run on Windows 7. So according to documentation that API is supposed to be imported from Kernel32.dll, but in reality (in my Windows 10 v1709) it is not.
I was able to find it in Kernelbase.dll instead:
So I'm wondering, can I dynamically load it from Kernelbase.dll instead?
this definitely bug in documentation. if we call (test on win10)
GetProcAddress(GetModuleHandle(L"kernel32"), "GetStagedPackageOrigin");
we got 0 - this mean that this api not exported or forwarded from kernel32.dll
but if call
GetProcAddress(GetModuleHandle(L"kernelbase"), "GetStagedPackageOrigin");
we got it real address.
next - when I search in latest sdk libs - I not found GetStagedPackageOrigin in kernel32.lib too. only one lib containing this symbol - OneCoreUap.lib umbrella library - and marked it exported from api-ms-win-appmodel-runtime-l1-1-1.dll .this dll resolved in runtime to kernel.appcore.dll. implementation - simply jump to kernelbase.GetStagedPackageOrigin
so most correct I think try import this api from api-ms-win-appmodel-runtime-l1-1-1.dll
very strange appraisal for my look :) with so simply question
anybody can easy test this simply code on win8.1, win10
GetProcAddress(LoadLibrary(L"kernel32"), "GetStagedPackageOrigin");//fail
GetProcAddress(LoadLibrary(L"kernelbase"), "GetStagedPackageOrigin");//ok
GetProcAddress(LoadLibrary(L"kernel.appcore.dll"), "GetStagedPackageOrigin");//ok
GetProcAddress(LoadLibrary(L"api-ms-win-appmodel-runtime-l1-1-1"), "GetStagedPackageOrigin");//ok
and view that by fact GetStagedPackageOrigin not exported from kernel32.dll. this is simply fact.
about lib file - i have no win8.1 sdk under hand, but i search this api in 10.x sdk version through lib files - and i found that this api implemented only in OneCoreUap.lib (not this symbol in kernel32.lib). and OneCoreUap.lib say that this api ix exported by api-ms-win-appmodel-runtime-l1-1-1.dll. so if we link with this lib - we by fact will be try import this api with api-ms-win-appmodel-runtime-l1-1-1.dll (this name will be hardcoded in our pe file). so we need or link with OneCoreUap.lib (i advice add it at the end of lib list) or direct call GetProcAddress(LoadLibrary(L"api-ms-win-appmodel-runtime-l1-1-1"), "GetStagedPackageOrigin");.
and can note that which header files use - absolute not related to question at all. if somebody not agree with this - can i ask - which lib need use - please concrete answer. and from which dll - please concrete dll name application will be use when use this lib (this dll name will be hardcoded in pe import table)
I would certainly not bind it to the versioned api-ms-win-appmodel-runtime-l1-1-1.dll , but the two generic ones. kernelbase or kernel.appcore.
The versions are visual studio/ucrt version specific.
When one should implicitly or explicitly link to a DLL and what are common practices or pitfalls?
It is fairly rare to explicitly link a DLL. Mostly because it is painful and error prone. You need to write a function pointer declaration for the exported function and get the LoadLibrary + GetProcAddress + FreeLibrary code right. You'd do so only if you need a runtime dependency on a plug-in style DLL or want to select from a set of DLLs based on configuration. Or to deal with versioning, an API function that's only available on later versions of Windows for example. Explicit linking is the default for COM and .NET DLLs.
More background info in this MSDN Library article.
I'm assuming you refer to linking using a .lib vs loading a DLL dynamically using LoadLibrary().
Loading a DLL statically by linking to its .lib is generally safer. The linking stage checks that all the entry points exist in compile time and there is no chance you'll load a DLL that doesn't have the function you're expecting. It is also easier not to have to use GetProcAddress().
So generally you should use dynamic loading only when it is absolutely required.
I agree with other who answered you already (Hans Passant and shoosh). I want add only two things:
1) One common scenario when you have to use LoadLibrary and GetProcAddress is the following: you want use some new API existing in new versions of Windows only, but the API are not critical in your application. So you test with LoadLibrary and GetProcAddress whether the function which you need exist, and use it in the case. What your program do if the functions not exist depend total from your implementation.
2) There are one important options which you not included in your question: delayed loading of DLLs. In this case the operating system will load the DLL when one of its functions is called and not at the application start. It allows to use import libraries (.lib files) in some scenarios where explicitly linking should be used at the first look. Moreover it improve the startup time of the applications and are wide used by Windows itself. So the way is also recommended.
I have a project compiled using __cdecl calling convention (msvc2010) and I compiled boost using the same compiler using the default settings.
The project linked with boost but I at runtime I got an assert message like this:
File: ...\boost\boost\program_options\detail\parsers.hpp
Line: 79
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
There are the following questions:
what calling convention does boost build with by default on Windows (msvc2010)
how to I compile boost with __cdecl calling convention
why boost wasn't able to prevent linking with code with different calling conventions? I understood that boost has really smart library auto-inclusion code.
Update #1
It looks that boost does compile and link with proper calling convention, still at runtime I get the above problem. I did a sample application using the same code and it works but in my application it fails. The only difference could be from project configuration or includes/stdafx.h
Just use
bjam ... **cxxflags=/Zp4**
while building boost libraries.
As far as I know there's not way to make C++ use cdecl calling conventions (see MSDN Calling Convention). The C++ method calling is just different from C. The only opportunity that you have to use one of the C calling conventions is for functions, which include class static functions in C++. If you know that's the case you can try forcing the option when building by adding the option during the build:
bjam cxxflags=/Gd ...
(see BBv2 Builtin features)
Or to make it "permanent" set up a user-config.jam with your compiler and add it to the build options for all BBv2 msvc builds (see BBv2 Configuration and related docs). As for you other questions:
Boost uses the default calling convention MSVC uses, except for cases where it overrides it at the code level. I don't know where those are as they are library specific. So you'd have to search the code for the "__*" code decorators.
See above for partial answer.
Detection; there are two reasons: There is a limit to how many different options we can reasonably detect for for building as it's an exponential growth of different possible variations so we limit it to the most important cases. And in the case of calling convention, it's not actually possible since it's something that can be changed on a per function basis.
I found the cause of the problem inside one of the shared property files: <StructMemberAlignment>4Bytes</StructMemberAlignment>
If I remove it the code will work. Still, I'm not sure why this is happening and how could I solve it without removing the above code (that was required by another library).
I added another question regarding boost and structure member alignment.
when you need to use a function you include a header file but wheres the function code is defined?
Dave, the code lives in the various and many DLL files in your Windows\system32 directory.
The actual code that implements the Win-32 API are defined in various DLLs on your system. These DLLs have names like kernel32.dll, comctl32.dll etc. You will find them in C:\Windows\System32.
What generally happens is that you link your code with kernel32.lib etc. that have a little code to dynamically load the DLLs when your program starts. This allows Win32 API functions to directly call into the DLLS.
Well as explained above you are in the hands of microsoft.
You can always look at the msdn http://msdn.microsoft.com.
For most API functions you can find some information at the bottom.
For most function you get from there:
Minimum supported client
Minimum supported server
Header
Library
DLL
Unicode and ANSI names
The canned DllMain for MFC 8.0 does not seem to call ExitInstance when it gets a DLL_PROCESS_DETACH. One possible solution is to define my own DllMain, but how do I tell the linker to use mine and not MFC's?
Or, is there another override which gets called on DLL_PROCESS_DETACH I'm not aware of?
I have had similar issues for a project compiled with /clr. Are you in the same situation? I was never able to trace it to a specific condition, but changing some static initializers to set null cleared it up. I think it has something to do with the order that static destructors are registered.
I'm not sure why your ExitInstance isn't called, but it's possible to define your own DllMain by copying the contents of MFC's dllmodul.cpp file into a file in your dll and adding any extra required functionality. The procedure is documented in this MS knowledge base article. Though it was written for MFC 4.0, I have used this method successfully for apps using MFC 8.0.