Arithmetics...



  • @remi said in Arithmetics...:

    Yes, but it's also @dcon kind of fucking with you.

    Actually, it was just me being :pendant:. Because someone would have pointed out there's more than 1 way to call a function in Windows.

    When you link to the .lib, your executable will simply not run if that DLL cannot be loaded at startup. With LoadLibrary, you defer that until runtime. As @remi mentioned, this is good for plugins and system dependent stuff (like invoking Win10-only functions from a binary that needs to still work on Win7).

    Not sure how pinvoke works since I don't do .net. Is it like a link-time thing? Or a runtime thing? (what I'm asking is what happens if that dll doesn't exist?)

    @blakeyrat said in Arithmetics...:

    but again once you do that they're no longer dynamically linked libraries.

    Yes they are. They aren't loaded until your program runs. And, yes, you could replace one. For instance, say I link to "foo.dll" that someone (oh so nicely </sarcasm>) installed into system32. If I now dropped my own foo.dll into my exe directory, I just changed what's loaded.


  • Impossible Mission - B

    @blakeyrat said in Arithmetics...:

    You only need to do that if it's not a .NET DLL. The DllImport attribute is part of the System.Runtime.InteropServices namespace, aka. "me want run C code!"
    Needless to say, if that's in your program, your perfectly portable C# code becomes instantly not-at-all-portable, sorry buddy.

    This is stated as a much stronger, more absolute "fact" than the truth: that it really depends on the library you're calling into. If you're calling winapi, sure. But there are plenty of other native libraries out there, and a lot of them are cross-platform.



  • @twelvebaud said in Arithmetics...:

    .NET modules include all the information that would go in a C++ header file in the module (DLL) itself, so you can actually go look at the definitions and see what's in there, even with no source code files, with zero loss in fidelity, using the exact same IDE windows and keyboard shortcuts you're familiar with from C++ development.

    Yes, I got that from Blakey's answer. That's neat. I suspected it could to that (given what I've heard about managed code etc.), but still, that's neat. I don't think it makes a huge difference with C++ code when you've got the headers, but of course this means you just need the DLL to work with it, not the DLL + headers, so it's more convenient (but not really related to what we started talking about here).

    Things get icky when doing Platform Invoke because the C# compiler can't read C++ header files.

    Mixing different languages in the same program is rarely easy or without problems, so that's not unexpected...

    #define WIN32_LEAN_AND_MEAN; #include <Windows> and chill.

    I didn't know that (I don't do tons of Windows dev), thanks.

    But you still have to know whether to link against Kernel32, User32, Shell32, Gdi32, or a bunch of other fun ones; Visual Studio just goes "screw it, I'm just going to include all of them and let the linker sort it out" by default.

    Sure, but to come back to my initial point, that is not something you have to worry about at the exact moment you are writing code, but when you compile it. And the same issue exists in all setups, as far as I can tell, there is always some point at which you have to find out where what you want is. But at least it's decoupled from the actual code itself.



  • @dcon said in Arithmetics...:

    @remi said in Arithmetics...:

    Yes, but it's also @dcon kind of fucking with you.

    Actually, it was just me being :pendant:.

    Some might say that this is the same thing... šŸ”„



  • @twelvebaud said in Arithmetics...:

    What usually happens is that you statically link not against the library itself, but against an export table. The linker then goes "cool, there's this function, with this calling convention and stack layout, and it's implementation is in outer space somewhere. I'll add that to my EXE ... 'outer... space... somewhere.' Good!" At runtime, the OS goes through the EXE's import table, loads all of the DLLs mentioned therein, and replaces the "outer space somewhere" stubs with proper links to the DLLs. That makes the links dynamic, in that you can replace the DLL with any other DLL that has the same names or ordinals in its export table and it still works. The loads are static, in that it always uses the same DLL name and the same function name or number.

    Interesting. I feel like I knew that at some time, but the knowledge fell out of my brain because fuck C++.

    EDIT: but this still leaves open the question: if the linker knows your code, when built, had a statement like #include <foo.h>... how does it know, when run months later on a completely different computer and OS, that "foo.h" is found in /Lunix/Lib/Barf/Foo and not in some other path? There must be some like lookup somewhere in the OS? The linker could obviously store the building computer's path in the executable somewhere, but how does it know where that path is on the running computer? Since Linux has no standardized paths for this shit.

    @twelvebaud said in Arithmetics...:

    Things get icky when doing Platform Invoke because the C# compiler can't read C++ header files.

    My perhaps out-of-date understanding is that very few people use C++ shared libraries, because the format of them can change between C++ compilers and between versions of C++ compilers. Meaning: you can't guarantee that your application compiled with MSVC can link to a DLL created by GCC.

    The solution for this is for everybody who isn't using a managed language (Java and C# do their own, far smarter, thing) builds their DLL with the C library format instead of the C++ format.

    Since they're C format, you have zero information about (for example) the types the library expects to be passed into each function. Which is why you have to manually tell C# "hey this function really takes an int and an array of bytes" or whatever at before you PInvoke it.

    ... but generally I try to avoid this entire mess because it's shitty and stick to managed code in the first place. When I do use PInvoke it's usually just copying an example found online.

    And maybe I'm totally wrong and ignorant about all of this, but somehow that doesn't seem to bother me much since it's boring bullshit.

    @twelvebaud said in Arithmetics...:

    #define WIN32_LEAN_AND_MEAN; #include <Windows> and chill. But you still have to know whether to link against Kernel32, User32, Shell32, Gdi32, or a bunch of other fun ones; Visual Studio just goes "screw it, I'm just going to include all of them and let the linker sort it out" by default.

    .NET's compiler is smart enough to automatically just include only the stuff you actually use in your code.

    @remi said in Arithmetics...:

    Right, so there is nothing different between [DllImport...] and LoadLibrary(...)?

    Well I said that like 4 posts ago, didn't I? I'm not sure what the confusion was.

    @remi said in Arithmetics...:

    Before you yell at me again, that is a true question. You said that LoadLibrary() "precludes the ability to change that path at runtime". It doesn't. So what's the difference in your mind?

    What I meant is the #include blah.h version, but that's because I didn't know that the linker didn't actually include the library, instead it just made a fake-o stub library and still did the actual real linking at runtime. Ignorance fought.

    @remi said in Arithmetics...:

    I am unaware of what C# IDE can do, for the simple reason that I don't fucking do C#.

    Well ok, but surely C++ (or whatever you do use) has good IDEs, yes? Otherwise why wouldn't you switch to something that does. Shitty tools suck.

    @dcon said in Arithmetics...:

    Not sure how pinvoke works since I don't do .net. Is it like a link-time thing? Or a runtime thing? (what I'm asking is what happens if that dll doesn't exist?)

    It's a runtime thing, and it throws exceptions like all operations in .NET that have the potential to fail.



  • @blakeyrat said in Arithmetics...:

    EDIT: but this still leaves open the question: if the linker knows your code, when build, had a statement like #include <foo.h>... how does it know, when run months later on a completely different computer and OS, that "foo.h" is found in /Lunix/Lib/Barf/Foo and not in some other path? There must be some like lookup somewhere in the OS?

    'cause the compiled program doesn't contain any reference to "foo.h", but only to the name of the functions from that file (and matching DLL) that you called in your code. So all it needs is the export table.

    There is no direct connection between the foo.h file and the DLL that was compiled with it. In theory, you could have a foo.h that entirely differs from the one that was used to build the DLL, as long as it defines the proper functions etc. This is of course a possible failure point of the system, when you get a DLL and the header files there is a possibility that they are not matching (for example if the 3rd party providing you with both botched their packaging... that does happen...).

    My perhaps out-of-date understanding is that very few people use C++ shared libraries, because the format of them can change between C++ compilers and between versions of C++ compilers. Meaning: you can't guarantee that your application compiled with MSVC can link to a DLL created by GCC.

    AFAIK, that's more or less true (the incompatibility), but not the first part. Most 3rd parties will provide DLL compiled with usual current versions of MSVC, so yes you're stuck with that version, but there aren't billions of those. And on Linux, there is more flexibility and libraries compiled with different compilers can work together (at some point we used stuff built from gcc + Intel compiler together).

    @remi said in Arithmetics...:

    I am unaware of what C# IDE can do, for the simple reason that I don't fucking do C#.

    Well ok, but surely C++ (or whatever you do use) has good IDEs, yes?

    Yes, it does, but since nowhere in my source code is there any direct reference to the DLLs themselves, I have no idea what an IDE would do with it. So really, you're beating around the wrong bush here.



  • @remi said in Arithmetics...:

    Yes, it does, but since nowhere in my source code is there any direct reference to the DLLs themselves, I have no idea what an IDE would do with it. So really, you're beating around the wrong bush here.

    Maybe; but when you say "I have to read a text file to see what's in a library" my brain goes instantly to "wow, welcome to 1986."



  • @blakeyrat said in Arithmetics...:

    And maybe I'm totally wrong and ignorant about all of this, but somehow that doesn't seem to bother me much since it's boring bullshit.

    Nope, that's all exactly right. C++ format is identical to C format except with "name mangling", where the compiler adds a bunch of I's and G's and @'s and junk to the end of the function name that somehow encode all the types, lengths, return value types, et cetera. But every compiler vendor mangles names differently, and can change how they mangle them at any time.

    @blakeyrat said in Arithmetics...:

    .NET's compiler is smart enough to automatically just include only the stuff you actually use in your code.

    It's actually dumber. With C++'s linker, if you don't call any functions from a particular library, that library is dropped from the final output, and the import table only lists the functions that are actually used. With C#'s, every reference you add ends up as a .reference in the final module, and the Windows Loader crashes the program out if they're not available, even if they're never used.

    @blakeyrat said in Arithmetics...:

    What I meant is the #include blah.h version, but that's because I didn't know that the linker didn't actually include the library,

    Another point in your favor: Static linking and dynamic linking in C++ use exactly the same source code syntax and command line arguments. The only difference is in the .LIB files that end up being passed to the linker.

    @blakeyrat said in Arithmetics...:

    if the linker knows your code, when built, had a statement like #include <foo.h>... how does it know, when run months later on a completely different computer and OS, that "foo.h" is found in /Lunix/Lib/Barf/Foo and not in some other path?

    The header file isn't used at all during linking; it already got textually dumped into your source code just before compilation from the includes path. What ends up happening is that the linker on the building machine looks through the list of all libraries it's been passed for each function name that the compiler said "this is from an external library", and references the first one it finds. (Yes, this has all the namespace collision problems you're thinking of.) If the .LIB says it's a shared library, the linker adds the bare name of the .LIB and the name of the function to a table, otherwise it ensures the whole library is included in the output and patches in the needed call or jump instructions. When the resulting program is run, the OS loader takes the bare name from the table and looks through its path for any DLL or SO with the same name (Yes, this also has all the namespace collision problems you're thinking of; welcome to DLL Hell), loads it in memory, and patches in the needed jump instructions.



  • @blakeyrat said in Arithmetics...:

    @remi said in Arithmetics...:

    The huge majority of source code will use #include <foo.h> and defer the DLL linking to, well, the linker (i.e. how you compile the code).

    ... but again once you do that they're no longer dynamically linked libraries. So yes that works, just like pulling a Toyota with a couple horses works, but you're kind of missing the point of the exercise.

    Actually that is exactly how .DLL's work on Windows. Static Libraries, on the other hand, cease to be libraries at link time as the actual bits are copied into the final file [which may be an .EXE or .DLL]



  • @thecpuwizard said in Arithmetics...:

    Actually that is exactly how .DLL's work on Windows.

    I assume C++ works like C++ no matter what OS it's on.

    But Windows has a very strict set of paths libraries can live in. With Linux, they're "eh where ever I guess". That was my second confusion.

    BTW, and I'm sure the answer is "no" because everything is as shitty as possible all the time forever, but is there at least some kind of central registry where a person wanting to make a "froglib" can check to see if there's already a library named "froglib"?



  • @blakeyrat said in Arithmetics...:

    But Windows has a very strict set of paths libraries can live in.

    No it doesn't. You can put them anywhere. There is a set of rules of where it will look. Which the program can change at runtime.

    If prog1 has a froglib and prog2 has a froglib and they both installed to their install dirs, there is no conflict. Now if they both try to install to system32. Well, they're both idiots and should be shot.



  • @remi said in Arithmetics...:

    Yes, it does, but since nowhere in my source code is there any direct reference to the DLLs themselves, I have no idea what an IDE would do with it. So really, you're beating around the wrong bush here.

    Let's use Visual Studio as an example, since I have it handy and it works with both languages. F12 is the default keybind for "Go to Definition" and it uses whatever symbol is under the cursor. Let's assume my cursor isn't on a local variable.

    If I'm working with C or C++, pressing F12 takes me directly to that specific .H or .HPP file. Doesn't matter if there's also a .C or .CPP file. Whether or not I understand that .H file depends on how perverse or baroque its #defines are, and I may need to F12 several layers deep to get a good picture of what's going on. Hopefully the library that provided that .H file is the one I'm writing or is also on the list of referenced libs.

    If I'm working with C# and I have the source code available, pressing F12 takes me to the corresponding source file, cursor at the statement that has that definition. Since C# uses #define only for conditional compilation and not for a macrolanguage, I'm pretty much guaranteed to understand what's there, but I can always F12 individual pieces if I need to. It gets irritating when dealing with interfaces or abstract superclasses, since you go to the declared type rather than an actual implementing type, but there's another key for that too. Since it's full source code, obviously it'll be available at link time.

    If I'm working with C# and I don't have the source code available, things change depending on what year it is. In 2012 and earlier, I'm taken to a graphical "Object Browser", which shows me a list of all definitions and has the one I need highlighted, but it's purely a visual interface. In 2015 and later, Visual Studio creates a synthetic C# file with all of the definitions that'd be in a header file as stubs, and adds "[from metadata]" to the tab name. I may not have the implementation, but since it's coming from the same module I'd link to, it's just as good.


  • Java Dev

    @blakeyrat Linux loaders get library locations from three places:

    • Hardcoded /lib, /usr/lib, and /usr/local/lib (and/or lib32, lib64 variants)
    • Locations specified in /etc/ld.so.conf and /etc/ld.so.conf.d/*
    • Locations specified in the environment variable LD_LIBRARY_PATH

    The linker will look in the same places, plus places passed to it explicitly via flags. Additionally applications can load libraries explicitly after they have been loaded, using dlopen("plugin.so") and dlsym(handle, "function"), and in this case they can also specify absolute paths to libraries in other directories.


  • ā™æ (Parody)

    @blakeyrat said in Arithmetics...:

    In any case, if you have to tell the linker about a DLL, it kind of defeats the purpose of it being a dynamicly linked library and just becomes a normal library. It also precludes the ability to change that path at runtime to, for example, load a DLL as a plug-in to your application.

    That's not true at all. It makes the runtime linking of the library a requirement when you run it, but you can still swap out the library for a different version. The paths used to load libraries varies by platform, but that's a different thing than what you're talking about.

    If you want to load a library actually dynamically, you can still do that, but now you're talking about something completely different. There are still other important differences between a dll and linking a static library, like the fact that the static library is literally included into your artifact (executable or library).



  • @blakeyrat said in Arithmetics...:

    @thecpuwizard said in Arithmetics...:

    Actually that is exactly how .DLL's work on Windows.

    I assume C++ works like C++ no matter what OS it's on.

    But Windows has a very strict set of paths libraries can live in. With Linux, they're "eh where ever I guess". That was my second confusion.

    BTW, and I'm sure the answer is "no" because everything is as shitty as possible all the time forever, but is there at least some kind of central registry where a person wanting to make a "froglib" can check to see if there's already a library named "froglib"?

    Also chiming in that Windows does NOT have "a very strict set of paths libraries can live in." they can live (at run time) in any folder, on any drive, including UNC.

    This has nothing to do with what the linker does, and the fact that the linker needs access to the .DLL (or at least the .idl, but that is rare these days) to determine the various entry points (which may be patched at run time due to dynamic address relocation - something virtually certain on modern machines).


  • :belt_onion:

    @thecpuwizard said in Arithmetics...:

    Also chiming in that Windows does NOT have "a very strict set of paths libraries can live in." they can live (at run time) in any folder, on any drive, including UNC.

    And including the Web. At least as of XP, you can put "\\<IP address>\<DLL name>" in your import table and the loader will go out, grab the DLL, and load it right up for you (with all the security implications thereof). You can craft a 133-byte dropper executable that does that.

    Haven't tested that in Windows 7+ but I'd be surprised if it were no longer the case. If you want a "strict set of paths libraries can live in", you use AppLocker or something like McAfee HIPS.

    Edit: And if you want a strict set of paths libraries can live in on Linux, you use AppArmor or SELinux. Windows isn't unique in the loader doing whatever you tell it to do.

    Interesting read for reverse engineers like me: http://archive.is/w01DO


  • :belt_onion:

    @thecpuwizard said in Arithmetics...:

    Also chiming in that Windows does NOT have "a very strict set of paths libraries can live in." they can live (at run time) in any folder, on any drive, including UNC.

    The above being said (as an interesting side note), I think blakey was referring to the safe DLL search mode, which is enabled by default from Windows XP SP2+: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx#standard_search_order_for_desktop_applications

    This does prevent, for example, an unprivileged user from manipulating a privileged process's search order. You can still play loader tricks but that's only useful to create e.g. a dropper as in my example; it doesn't get you privilege escalation.



  • @heterodox said in Arithmetics...:

    @thecpuwizard said in Arithmetics...:

    Also chiming in that Windows does NOT have "a very strict set of paths libraries can live in." they can live (at run time) in any folder, on any drive, including UNC.

    The above being said (as an interesting side note), I think blakey was referring to the safe DLL search mode, which is enabled by default from Windows XP SP2+: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx#standard_search_order_for_desktop_applications

    This does prevent, for example, an unprivileged user from manipulating a privileged process's search order. You can still play loader tricks but that's only useful to create e.g. a dropper as in my example; it doesn't get you privilege escalation.

    Does not change anything... Look at the details when enabled:

    1. The directory from which the application loaded.
    2. The system directory. Use the GetSystemDirectory function to get the path of this directory.
    3. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
    4. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
    5. The current directory.
    6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

    #6 can point to ANY directory.

    All this does (which is quite important but also immaterial to the discussion), is attempt to prevent "hijacking" of DLLs that would normally be loaded from a system directory.


  • :belt_onion:

    @thecpuwizard said in Arithmetics...:

    All this does (which is quite important but also immaterial to the discussion), is attempt to prevent "hijacking" of DLLs that would normally be loaded from a system directory.

    That's exactly what I said. I'm explaining what blakeyrat meant, which is not immaterial to the discussion, as we're discussing dynamic linking/loading ā€” maybe slightly tangential, but then, welcome to WTDWTF.



  • @berniethebernie said in Arithmetics...:

    Steven tried to prevent the issues with a cast to long - but a negative int still translates into a negative long... Actually, an unchecked subtraction Environment.TickCount - GetLastInputTime() (the return type of the latter fixed before, of course) does the trick (and is described on StackOverflow, by the way).

    There still seems to be plenty of :wtf: in there.

    When working with timers and timeouts, it is usually better to maintain a deadline rather than time left, because that way inaccuracies in tracking the current time don't skew it and the math is generally simpler that way anyway. So the way I'd do it is that I'd have an inactivity timeout, set it to now + 60 when the user does something and calculate deadline - now for display. That should avoid risk of overflow.



  • @blakeyrat said in Arithmetics...:

    @remi said in Arithmetics...:

    Yes, it does, but since nowhere in my source code is there any direct reference to the DLLs themselves, I have no idea what an IDE would do with it. So really, you're beating around the wrong bush here.

    Maybe; but when you say "I have to read a text file to see what's in a library" my brain goes instantly to "wow, welcome to 1986."

    I never said that, stop listening to your aliens. I said that having the includes in C++ allowed to "look into those files", but the way it actually is done depends on your IDE. And of course modern ones will offer nice presentations of those files, indexes, lists of functions and what not. Remember I was saying that because at that time I wondered that a C# DLL was just a binary black box and therefore I thought it was not usable in any friendly way while developing.

    Now I was wrong on C# DLLs, so that point becomes moot. But stop bringing everything back to your pet-peeve hatred of text files. You were the one who erroneously assumed that "looking into headers" meant reading the raw text file. I can accept that my initial wording was somewhat ambiguous, but I clarified that point the first time you brought it up, and it's now at least the 3rd post where you keep coming back to it. Stop it. That is disingenuous.



  • @twelvebaud said in Arithmetics...:

    @remi said in Arithmetics...:

    Yes, it does, but since nowhere in my source code is there any direct reference to the DLLs themselves, I have no idea what an IDE would do with it. So really, you're beating around the wrong bush here.

    Let's use Visual Studio as an example, since I have it handy and it works with both languages.

    I'm not sure what your point is here... Is it to explain to me what it does in C#? If so, thanks, I appreciate it (seriously, that's not sarcasm), but blakey explained it already, so you're a bit late to the party (the post you're replying to was trying to clarify why I was asking that question in the first place, but it comes after it had been answered).

    Is it to say that exploring headers in C++ is less friendly than exploring assemblies in C#? It does look like that's what you're saying, and it may very well be the case. I never said otherwise, and I'm sure (actually, the opposite would be a design failure!) that a language designed from the start to work with its IDE, to integrate various DLLs, to manage several bits of code etc. like C# would do that better than C++. But really, that's unrelated to what I said. I'm not on a rant as to which language is the best.

    Also, you are mixing the ease of access to the information vs. how readable (understandable) it is. The fact that some C++ headers overuse #define doesn't mean all C++ code does and will be hard to understand because of it (plus, if your IDE doesn't show you what #defines are, you've got a bad one), nor does the fact that most C# files don't mean that they will be easy to understand (well again I don't do C#, but don't tell me that there is no unreadable code in C#!).

    In 2015 and later, Visual Studio creates a synthetic C# file

    Don't tell that to blakeyrat, he'll scream that looking at a text file is so 1986.



  • @remi said in Arithmetics...:

    if your IDE doesn't show you what #defines are, you've got a bad one

    There is evil code in the world, some of it is quite functional... A pseudo example...

    #define X(y) .... // some definition
    #include "f.h"
    #define X(y) .... // another definition
    #include "f.h"
    #define X(y) .... // different definition
    #include "f.h"
    #define X(y) .... // one more definition
    #include "f.h"

    Note that this is actually simplified. Imagine includes of includes that conditionally include other headers that change the #define.

    When I had to work on this code, I would first run the preprocessor, then use those files for compilation/debug/fix. Once I knew the necessary change, I would figure out how to approach it in the original environment.

    Horrible, without a doubt. But this style of code was written by the only person I have ever met who could keep track in is head the state of multi-core/hyper-threaded pipelines and cache synchronization. Nobody could touch the level of performance he got [and this was extreme real-time code - not Windows or Linux]



  • @thecpuwizard said in Arithmetics...:

    There is evil code in the world

    There is indeed (some people say there is something called a "front page" on this site with stories about such stuff...). But that's not really related to what I was discussing...



  • @remi said in Arithmetics...:

    @thecpuwizard said in Arithmetics...:

    There is evil code in the world

    There is indeed (some people say there is something called a "front page" on this site with stories about such stuff...). But that's not really related to what I was discussing...

    Well, that was how I understood...

    @remi said in Arithmetics...:

    if your IDE doesn't show you what #defines are, you've got a bad one

    Showing that a #define exists is basically useless. Showing what a #define is (what the preprocessor will evaluate it to) has value - BUT is very context sensitive.

    Using the sample I posted above, find me an IDE that will allow me to be inside of f.h and view the meaning of X - I have never found one, but perhaps all I have are "Bad" IDEs.



  • @blakeyrat said in Arithmetics...:

    In any case, I don't know the answer to your question. Look it up. But if it is required, since Attributes in C# are just methods, it'd be easy enough to write a version that checks the ".dll" path and if there's no file there also checks the ".so" path. So it's not like a huge emergency anyway.

    Warning :pendant:ry ahead, my apologies in advance...

    Attributes in C# are actually classes, usually annotating to a runtime or framework that something non-default is appropriate. In the case at hand the DllImportAttribute is applied to a static extern method. When code tries to call the static extern method the .Net runtime will read the (properties on the) annotation and perform the LoadLibrary/GetProcAddress dance to get to the actual code, and uses other properties and annotations to determine the calling convention for the method, the string format (length-prefixed, zero terminated, COM, single/multi/unicode/utf-8 encoding), it takes care that objects are pinned in memory (i.e. can't be moved by the garbage collector) for the duration of the method call, and a whole lot more.
    The runtime is free to take the dllname as 'hint', e.g. mono on linux translates DllName.dll to libDllName.so, and supports a "dll mapping" configuration, for those cases where it's not that simple.
    On the .Net framework, depending on some parameters, the proc name is adapted at runtime - name + 'A' on ANSI based, name + 'W' on Unicode based Windows'.

    All that said, and while it is an interesting subject, it is quite a pain to work with (there's a reason someone started pinvoke.net). Everything is so much easier when it is in the same eco-system and runtime. And if you must use it you always try to isolate it as much as possible from the rest of your code.


  • Considered Harmful

    @remi said in Arithmetics...:

    @blakeyrat said in Arithmetics...:

    @remi said in Arithmetics...:

    Yes, it does, but since nowhere in my source code is there any direct reference to the DLLs themselves, I have no idea what an IDE would do with it. So really, you're beating around the wrong bush here.

    Maybe; but when you say "I have to read a text file to see what's in a library" my brain goes instantly to "wow, welcome to 1986."

    I never said that, stop listening to your aliens. I said that having the includes in C++ allowed to "look into those files", but the way it actually is done depends on your IDE. And of course modern ones will offer nice presentations of those files, indexes, lists of functions and what not. Remember I was saying that because at that time I wondered that a C# DLL was just a binary black box and therefore I thought it was not usable in any friendly way while developing.

    They've got the same file extension, but they're radically different concepts. A C# DLL is pretty much the same unit as a JAR file - a set of classes made out of CLR bytecode. Very easy to crack open, very easy to decompile.



  • @pie_flavor said in Arithmetics...:

    They've got the same file extension, but they're radically different concepts.

    I think that's what got me confused. Because they look externally the same, I thought C# would not have gotten much more info out of it than C++ does. I was entirely wrong on that.



  • @thecpuwizard said in Arithmetics...:

    Using the sample I posted above

    Using bad (or convoluted, or unusual) code, you can always find cases that are hard to follow and understand or that will confuse the IDE. That's not the point. Unless you claim there is never any possible way to write confusing code in C#, but somehow that doesn't seem a realistic statement.

    find me an IDE that will allow me to be inside of f.h and view the meaning of X

    You found an example where "be inside of f.h" means that "the meaning of X" is not unique, so basically you're writing i = 0; f(i); i = 1; f(i); and then complaining that when you are looking at the code of f() you can't see the value of i. Well, duh.



  • @pie_flavor said in Arithmetics...:

    They've got the same file extension, but they're radically different concepts.

    Not really, they have the exact same file format, internal layout, external access points, et. al.

    The only thing that is different is the content.


  • Discourse touched me in a no-no place

    @blakeyrat said in Arithmetics...:

    But Windows has a very strict set of paths libraries can live in.

    It's rather more complicated than that. Those are the places where it searches when it doesn't know exactly where to look, but if you take over the loading process a bit more completely then you can supply the low-level linker with exactly where the library is and it is totally cool with just using that. This is incredibly relevant for dynamic library loading for plugin modules, and nothing like so important when you're dealing with libraries known at build link time.

    With Linux, they're "eh where ever I guess".

    It's just got different set of places where it should look; there's some nuances involved but it's overall a ā€œmehā€ sort of difference.


  • Discourse touched me in a no-no place

    @twelvebaud said in Arithmetics...:

    depends on how perverse or baroque its #defines are

    Hehehehehehehā€¦ :(


  • Discourse touched me in a no-no place

    @remi said in Arithmetics...:

    You found an example where "be inside of f.h" means that "the meaning of X" is not unique, so basically you're writing i = 0; f(i); i = 1; f(i); and then complaining that when you are looking at the code of f() you can't see the value of i. Well, duh.

    There are certain headers in LLVM that are examples of this. If you define one thing, you get a sequence of strings (comma separated), if you define another, you get an enum definition, and if you define a third you get a parser. In the same header. Fortunately, there's method in this madness: the headers that do this are all automatically generated from a much more compact form.

    It's still ugly, but it's marginally better than the alternatives.



  • @dkf said in Arithmetics...:

    It's still ugly, but it's marginally better than the alternatives.

    I wonder what the measurement of "better" would be if one compared massive preprocessor with generic programming??? [clearly this mandates C++ and the more recent the bigger the advantages to GP]


  • Discourse touched me in a no-no place

    @thecpuwizard said in Arithmetics...:

    I wonder what the measurement of "better" would be if one compared massive preprocessor with generic programming???

    The real starting point is a non-trivial file and we're talking about building tables with 10k elements in them. You might be able to parse that all with templatesā€¦ but why would you bother when you can use a separate build stage to make much more easily digestible intermediate files? Those are the ones that I was talking about. (Also, I only needed some of the things that the file was capable of defining; I have a different way of doing parsers that's actually faster in my use cases.)



  • @dkf said in Arithmetics...:

    @thecpuwizard said in Arithmetics...:

    I wonder what the measurement of "better" would be if one compared massive preprocessor with generic programming???

    The real starting point is a non-trivial file and we're talking about building tables with 10k elements in them. You might be able to parse that all with templatesā€¦ but why would you bother when you can use a separate build stage to make much more easily digestible intermediate files? Those are the ones that I was talking about. (Also, I only needed some of the things that the file was capable of defining; I have a different way of doing parsers that's actually faster in my use cases.)

    Wasn't referring to a specific case... and given how much work I have done with templates, I probably could; but you are right "should" is a different question...

    For your case, I do find it interesting (based on the very limited info) that you generated intermediate file that contained preprocessor pragmas rather than generating the code itself (i.e. post pre-processor source), especially since it is (apparently) part of an automated build process.


  • Discourse touched me in a no-no place

    @thecpuwizard said in Arithmetics...:

    I do find it interesting (based on the very limited info) that you generated intermediate file that contained preprocessor pragmas rather than generating the code itself

    I didn't do the preprocessing; that file is part of any developer installation of LLVM. My code just uses it by #defineing the right symbol and #includeing the file.


  • ā™æ (Parody)

    @thecpuwizard said in Arithmetics...:

    There is evil code in the world, some of it is quite functional... A pseudo example...
    #define X(y) .... // some definition
    #include "f.h"
    #define X(y) .... // another definition

    That's not functional, that's my wifeimperative!



  • @remi said in Arithmetics...:

    Don't tell that to blakeyrat, he'll scream that looking at a text file is so 1986.

    On the contrary; I recognize that embedding a tree view (which is what the Object Browser is) overlaid over a text editor is awkward and weird, and Visual Studio's current behavior makes more sense.

    So congratulations on being wrong.



  • @blakeyrat So looking at a text file is 1986 and bad, unless it is not? Thanks for clarifying. :trollface:



  • @pie_flavor said in Arithmetics...:

    They've got the same file extension, but they're radically different concepts.

    Not... really? It's just a small extension of the normal PE file format used by Windows executables and libraries. It's also got an ECMA number.

    I think the real problem is that C/C++ just suck and don't use the format even remotely close to its potential.



  • @remi said in Arithmetics...:

    So looking at a text file is 1986 and bad, unless it is not?

    If the best way of presenting the information (considering the current context and the limitations of space) is text, then it should be presented as text. The tree view works great when you have a lot of vertical space to open expandos.

    There's still no fucking excuse why I can't, in 2018, drag a PNG into my code file as a comment. Nor is there no excuse for people taking database classes at universities and not being taught the the GUI editor. Nor is there any excuse for a source control product made in 2008 not being equipped to power GUI clients. Etc.



  • @remi said in Arithmetics...:

    Of course we have to care about that when compiling it

    Not even then. The compiler only needs to know "there is a function called this and that that exists somewhere else."
    The linker then does the work of finding and attaching the actual code for the function to the function calls, whether they're in static libraries to be added to the final executable or in dynamic external libraries.



  • @blakeyrat said in Arithmetics...:

    There's still no fucking excuse why I can't, in 2018, drag a PNG into my code file as a comment. Nor is there no excuse for people taking database classes at universities and not being taught the the GUI editor. Nor is there any excuse for a source control product made in 2008 not being equipped to power GUI clients. Etc.

    Some people do write their source code in MS Word. I think it's the Enlightened thread, so you know what that says about that. šŸ¹

    However, you could write your own compiler that accepts .doc files as input! :trollface:


  • Discourse touched me in a no-no place

    @djls45 said in Arithmetics...:

    Some people do write their source code in MS Word.

    I take it you weren't thinking of VBA thereā€¦



  • @dkf No, I write that in Excel.


  • BINNED

    @djls45


  • BINNED

    @dkf said in Arithmetics...:

    @djls45 said in Arithmetics...:

    Some people do write their source code in MS Word.

    I take it you weren't thinking of VBA thereā€¦

    Probably not. "He wants to write his code in Word" was my thought, too.


  • Considered Harmful

    @blakeyrat said in Arithmetics...:

    There's still no fucking excuse why I can't, in 2018, drag a PNG into my code file as a comment.

    I think the excuse is that it's completely useless, that there's no other application of the complexity it would introduce, and that it introduces a shit ton of complexity when you'd get a lot farther by the editor auto uploading such an image to Imgur and pasting the link in the file, and having the image appear when you hover over the link.


  • BINNED

    @pie_flavor You could easily include an <img> tag or markdown-style syntax in a comment and have the IDE be smart enough to render it inline. But then he'd complain about Markdown.


Log in to reply