Comments (11)
the compiler generates slightly different code when it needs to reference an imported function, since the compiler is aware of the special way imported functions are implemented.
https://devblogs.microsoft.com/oldnewthing/20060724-00/?p=30403
If you forget to declare a function as dllimport, then you’re basically making the compiler act like a naive compiler that doesn’t understand dllimport. When the linker goes to resolve the external reference for the function, it will use the stub from the import library, and everything will work as before. You do miss out on the optimization that dllimport enables, but the code will still run. You’re just running in naive mode.
https://devblogs.microsoft.com/oldnewthing/20060726-00/?p=30363
The fact that names in import libraries are decorated means that it is doubly crucial that you use the official import library for the DLL you wish to use rather than trying to manufacture one with an import library generation tool. As we noted earlier, the tool won’t know whether the ordinal assigned to a named function was by design or merely coincidental.
https://devblogs.microsoft.com/oldnewthing/20060727-00/?p=30343
from glew.
Is there a specific issue you're having?
The binary API is essentially frozen, there would a lot of reluctance to change this.
from glew.
I am not requesting to change the binary API. I am just saying that there is neither need for dllimport
nor GLEW_STATIC
, especially when you build GLEW as a static library. Because when you compile an app for Windows to consume GLEW, by default (without GLEW_STATIC
defined) you get __imp_
prefixed external symbols. And, when you try to link your app to GLEW statically you get unresolved symbols. At the same time, you do not need dllimport
when writing code which is going to access symbols in a DLL. dllimport
is a relic of Cygwin. Some will argue that it enables application developers to select on a per symbol level the source of a symbol in the source code when linking to static and dynamic libraries at the same time. However, this decision should and can still be made by the application developer (GLEW’s consumer) in their own code, not in GLEW’s headers.
from glew.
My perception of dllimport
is that it's rather more conventional than being a "relic of Cygwin". But I do follow your reasoning and think it has technical merit. The practical problem is that if I get this wrong and widespread breakage results, I will likely get flooded with nasty outrage, the internet being how it is. I don't think using and requiring GLEW_STATIC is such a burden, but I admit that I just expect Windows development to be needlessly "annoying" like this.
from glew.
I guess one thing for me to revise is the implications of having the __imp_
prefix, or not. I do regard that as an ABI change, but what is the risk of that change more broadly?
from glew.
Using __declspec(dllimport) is optional on function declarations, but the compiler produces more
efficient code if you use this keyword. However, you must use __declspec(dllimport) for the importing
executable to access the DLL's public data symbols and objects. Note that the users of your DLL still
need to link with an import library.
from glew.
https://learn.microsoft.com/en-us/cpp/build/importing-and-exporting?view=msvc-170
Use the keywords __declspec(dllimport) or __declspec(dllexport) in a function definition in the main application
dllexport
is meant for and still used by library authors. dllimport
is/was meant for application authors, especially in the days before import libraries (like WinNT 3.51 and earlier). Application authors should decide which symbol and which not to import from a DLL. This decision should not be made by library headers. Today, this decision is usually made at link‑time by choosing either a static library or an import library (hence the word import in the name 😉). GLEW produces an import library by default. So yes, technically libraries can make this decision (as GLEW does) but by convention they do not and should not, especially when they provide an import library. In legacy toolchains, I think in pre‑MSVC 6.0, you had to use dllimport
at least on data symbols (this is probably also a reason why dllimport
s have been added throughout GLEW). However, I think since MSVC 6.0, you do not have to do even this anymore. The linkers of all toolchains have been upgraded to do this automatically long time ago. All extern
symbols are just resolved at link‑time, no matter whether they are found in a DLL or a static library. Furthermore, I think since MSVC 7.0 or maybe even earlier, Microsoft has stopped adding __imp_
prefixed symbols to their import library releases.
This is the only hint of that transition I could find now. Argh, if I could only find a properly archived MSDN somewhere… There was a nice article about this.
For example, the Windows SDK headers do not use virtually all symbols in the headers can only be found in DLLs, and at link‑time in import libraries.dllimport
although
dllimport
should also enable you to link to a DLL, in other words import a symbol, if you do not have an import library of that particular DLL. But, since GLEW produces an import library there is no need for doubling the effort (and creating confusion).
…, but doing so allows the compiler to generate better code.
…, but the compiler produces more efficient code if you use this keyword.
This claim in the docs is basically unsubstantiated and I am not even sure where this may be coming from. Maybe symbol lookup at link‑time can happen a bit faster? But, the compiler does not really have much to do with that.
My perception of
dllimport
is that it's rather more conventional than being a “relic of Cygwin”.
It is a “relic of Cygwin” in that sense that Cygwin kept using this explicit symbol importing mechanism when Microsoft and other toolchain makers have already moved on long time ago to import libraries.
what is the risk of that change more broadly?
You should not break much because all modern toolchains do not need dllimport
to work properly. People using ancient toolchains may need this but then 🤔 who would want to use obsolete toolchains and the artifacts they produce? In this case people can still add dllimport
to the symbols they need in their code.
from glew.
Although these are not the articles I had in mind they are also definitely enlightening. Thank you for digging these up. 👍
So, I guess we learn that dllimport
reduces one level of indirection, which does result in less binary code produced by the compiler, however the gains are minuscule. This reminds me that I might have read about dllimport
’s obsolescence in the context of Microsoft’s LTCG or GCC’s LTO. Because like the name says, there is code generation involved when linking. So, maybe it was in that context. Because if my memory serves me right, during LTCG or LTO the linker effectively creates __imp_
prefixed symbols before finally linking which has exactly the same effect Raymond Chen describes. I will have to search more on LTO.
Though, much of what Raymond Chen talks about there is often closely related to x86 (only). So, I guess one has to be careful when dealing with other architectures.
Interestingly, he says something about that I have also observed and mentioned this:
🤭 I guess his hopes have been in vain to this day. The Platform SDK (now renamed to the Windows SDK) headers still have not been attributed with , probably due to the linker upgrades over time.dllimport
. So, apparently it has been deemed not as important as things may seem
Anyhow, having dllimport
declarations in a header does not do any harm per se, it is just that you have to basically guard those symbols with a macro and define it when you want to link them statically. I guess, it is an inconvenience one can live with but with the downside that you always have to dig up the exact static guarding macro’s name while at the same time this problem has been solved in modern linkers.
from glew.
I'm sincere in saying that I didn't intend to tour this particular rabbit-hole, but a bit glad to have had a look and a conversation.
So far I'm leaning towards status-quo. Some reasoning:
- It still seems to be what Microsoft recommends as best-practice.
- GLEW is a C library intended for maximum portability, including obsolete compilers.
- There isn't much reward (for me) in making a change, but risk of breakage, and resulting maintainer grief.
- GLEW has been around a long time, has accumulated a fairly large install-base, I think that stability is generally valued.
- I don't happen to have old MS compilers to test with, and not motivated to go above and beyond to test for real.
- It's irritating to deal with the import/export/static macro stuff, but it's nothing new or unique to GLEW.
- Considering it's still required for data exports, doesn't seem unreasonable to be consistent.
Having said all that, I'm not sure dllimport is completely obsolete, but probably still appropriate for such an entrenched and old-school software module.
from glew.
Yeah, everything you are saying sounds reasonable und I fully understand that you want to minimize any chances of braking something.
I have opened this issue because GLEW was the only dependency in the project I am currently working on that requires you to define a macro at compile‑time when you intend to link statically later, which in my humble experience is quite unusual. It took me more than a day to figure out what was going on. Maybe I should have looked into GLEW’s documentation and source code a little bit earlier but since it is a kind of inherited project there was seemingly no reason for me to look more closely into this particular dependency than others. Anyhow, I have solved the issue in the project and have learned something new about dllimport
. 😄
This should close #385. Thank you for your assistance. 👍
from glew.
The Platform SDK (now renamed to the Windows SDK) headers still have not been attributed with
dllimport
.
Just FYI, the function declarations in the Windows SDK headers have been indeed specified with dllimport
. I must have missed something the first time or have been only looking at the WINAPI
macro. The WINBASEAPI
and DECLSPEC_IMPORT
macros are substituted with dllimport
specifiers.
I wonder however how do they handle function declarations that can be linked dynamically and statically without the need for an additional macro because the Windows SDK ships with a (though obsolete but nevertheless existing) static C runtime library. And, I do not recall defining one just in order to link statically later. Well, it was long time ago. 😀
from glew.
Related Issues (20)
- GLsizeiptr is supposed to be unsigned HOT 3
- How to compile glew on windows with osmesa?
- Use glew "locally"? HOT 1
- glewInit() fails if call EnableNonClientDpiScaling HOT 2
- Port python scripts to python3 HOT 4
- Files missings during build HOT 2
- Am I hallucinating or is there no include folder in the repo? HOT 2
- Is CMakeLists.txt maintained? HOT 4
- How do I compile with make include 32 bit on Ubuntu 64 Bit?
- Change CMake min version HOT 4
- Undefined references when compiling source HOT 3
- Building library fails on cmake and Makefile HOT 3
- CMakeLists is illformed
- arm64 on mac HOT 18
- Suddenly can't build GLEW anymore HOT 5
- definition of GLsizeiptr is inconsistent with Khronos gl32.h on armel and armhf HOT 1
- cmake: Undefined reference to glx functions when build with non-standard prefix path
- Bug - Files not found
- Regression testing of GLEW HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from glew.