Hiding the console from D while linked with C-version SDL2 - interop

Basically, I get a console window I don't want to see while writing SDL-windowed applications.
In C, the answer is simple: change your linker SubSystem to Windows; then SDL does the rest. It has a macro that redefines your main to SDL_main, which it calls from inside its own hidden WinMain function. Just make sure you take arguments in your main function and all goes smoothly.
In D, I'm having a little more trouble with it. Upon simply changing the subsystem by passing -L/SUBSYSTEM:WINDOWS to the linker, it informs me that I have declared main, SDL has declared WinMain, and it doesn't know how to deal. I thought changing the signature from void main() to extern(C) int SDL_main(int argc, char*[] argv) would solve the problem, but then the linker says it can't locate any of D's runtime symbols. Might have something to do with the entry point being written in C?
On the other side, my problem might be with how I have set up Derelict. I am working from this repository, which is a live-updated amalgam of all the different Derelict repositories on GitHub. In my VisualD solution, I have three relevant projects: a home-brewed Derelict project containing the source to SDL2 and the Utilities library, and the C-API SDL2 and SDL2main projects as found here. I compile and link to all three resulting libraries -- Derelict and SDL2main are static, SDL2 is dynamic. I am less inclined to say this setup is to blame, because it works just fine save the undying console window.

In the command line passed to DMD, add the linker option -L/SUBSYSTEM:WINDOWS

In case you use dub (which i recommend) and gdc, insert the following into your dub.json file:
"dflags": ["-Wl,--subsystem,windows"]

Related

Redirecting mangled functions via DLL proxying

I'm fiddling around with an old game and am trying to learn how it works. My current experiments include trying to proxy one of the game's DLL.
So I renamed the original DLL.dll to trueDLL.dll, dumped the DLL's exports with dumpbin and created the #pragmas (fine for now, I'll look into .def files later) to generate an "empty" proxy. This worked as expected.
Now, I'd like to redirect some of the functions to my reverse engineered implementations to test if they work. This is where I got stuck. Here's an example: the LogDebug function. The "empty", working pragma in the proxy DLL look like this:
#pragma comment(linker, "/export:?LogDebug##YAXPBDZZ=trueDLL.?LogDebug##YAXPBDZZ,#504")
I thought I could change the pragma like so to redirect the call to my implementation:
#pragma comment(linker, "/export:?LogDebug##YAXPBDZZ=LogInfo,#504")
Running the program, it fails to start because it can't find ?LogDebug##YAXPBDZZ. Some research shows that the ##YAXPBDZZ part isn't exported in my DLL. It appears to be some kind of info represented in the mangled name, but I couldn't find out what it actually means. Ghidra and this demangler aren't helping either, and the only search results are in russian.
Using VS 2019, no project settings are altered.
What is the problem here and how would I go about making this work? Or is there an easier/better way of achieving this? I'd like to avoid hooking the calls in the program exe for now but if I have to, I'll do it.
EDIT - Mangling scheme and compiler
I don't know exactly what was used to create DLL.dll, but according to Ghidra it was visualstudio:unknown. I'd interpret that as a 1998 (game file dates) version of MSVC. I'm using the current MSVC compiler (CL ver. 19).
It'd make sense for a current CL to use the C++ scheme. Looking at this page, and comparing it to the exports, DLL.dll appears to be using the C++ scheme too, but I could be wrong. How do I find this out for sure?
It turns out that the method in my DLL doesn't need the #pragma, as it actually overwrites the desired behaviour. If I define my function like undname.exe says and just add a __declspec(dllexport) in front, everything falls into place nicely.

g-wan: building library outside of /csp, and g++ compilation problems

I am giving Gwan a whirl.
Having made it through example code, I started a small project with more than one source file. I now have two problems:
I got a linking error at server startup:
Linking main.cpp: undefined symbol: _ZN7GwanUrl9concatAllEv
(the main file #includes the two other files; all the files are in the csp directory)
As an alternative to having all the files in the /csp directory, I would like to make a library outside of the /csp directory while still using some of the gwan functions. sadly, a tonne of errors follow -- WHEN I GCC from commandline not via G-WAN Startup.
In file included from /home/ec2-user/gwan/include/gwan.h:22,
from Xbufstream.h:10,
from Xbufstream.cpp:10:
/usr/include/time.h:199: error: ‘size_t’ does not name a type
.....
Anyone knows what the gwan g++ argument string looks like?
(odd the 1. and 1. its 1. and 2. in the editor)
First, this is not a linker issue: you have "undefined symbol" rather than "unresolved symbol" as an error.
This is simply an #include issue.
define the main() function in your script.cpp file.
there's a G-WAN folder dedicated to user-defined include files called /gwan/include but you can as well use /csp/my_include.hpp... if you are using the right syntax:
For example, having #include "toto.hpp" in /csp/hello.cpp lets me reach C++ functions defined and implemented in the gwan/include/toto.hpp file (or defined in toto.hpp and implemented in a pre-compiled library linked to your script with #pragma link).
If you rather use #include <toto.hpp> then the SYSTEM INCLUDE PATH will be searched instead (and this will work providing that your library was correctly installed).
If you want to use #include "toto.hpp" for a custom folder that was not setup in the system, you can use G-WAN's #pragma include "../my_folder" directive to specify its PATH or you can explicitely specify it in each include: #include "../my_folder/toto.hpp".
Nothing fancy there, only C/C++ dependancy rules apply (and G-WAN really helps by providing alternate ways that do not involve system settings).
For libraries (see the G-WAN examples for SQLite, Cairo, mySQL, cURL, etc.) you can either use pre-installed libraries that exported their location in SYSTEM variables... or put your library in the /gwan/libraries folder and their include file in the /gwan/include folder.
When writing your own libraries, remember that they need to be pre-compiled. This means that you obviously cannot use G-WAN symbols since your compiler may #include "gwan.h" (to have the definitions) but your linker will not know from where G-WAN symbols can be found. The way around is to always use the G-WAN API from the G-WAN scripts. Your custom libraries must either be general-purpose or buffer any payload intended to be used by G-WAN. No-double copy is needed since G-WAN provides the set_reply() call to let G-WAN use persistent replies built without the reply xbuffer provided by G-WAN servlets.
Now, a last word about linking (which was not the cause of your trouble but could participate to the confusion). If you mix C and C++, use extern C {} to wrap your C++ prototypes called from C (otherwise you will really have "unresolved symbols").
With all this information, you should be ready to face every possible situation.
the issue of referencing gwan.h symbols inside #include files can also be solved by moving all code into the header file, whether its .h or .hpp
its ungraceful but a fix nevertheless. and good enough for the simple extension i wanted.
looking into the /libraries/sqlite3/sqlite.h helped.
#gil, thanks for your time.

Correct way to export a DLL function on Mac OSX

I'm trying to compile a simple DLL on a Mac OS X 10.6, and am confused about the proper way to declare a function that the DLL offers up for the world to use. Following sample code from a reliable source, I came up with:
__declspsec(dllexport) pascal int ReturnTheNumberFive(void)
but gcc barfs on it. What the sample code actually had was MACPASCAL and DLLExport, which I assumed were macros. I grepped through the sample codes, SDKs, etc for #defines and plugged in what I found. These definitions could have been buried inside #ifs, so what I found isn't good and true. Illogically, the compiler also barfs if I just do the obvious and use DLLExport and MACPASCAL, so that's no solution.
What is the correct way to make a DLL's function available to apps?
By default, all symbols are visible in a .dylib. There are no calling convention changes (such as Pascal calling convention)
So, in short:
int ReturnTheNunmberFive(void) { return 6; }

How do I compile boost using __cdecl calling convention?

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.

Producing small Windows binaries

When developing and deploying native Windows applications, I often need to install a runtime before being able to run my binary, or statically link the library with my binary. For instance, after building a "Win32 Console" project with Visual Studio 2008, attempting to run the program on a fresh Windows 7 image results in:
The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
Issues like this one have been brought up in other posts on StackOverflow.
How does one develop applications that don't require runtimes that aren't already on the target OS (i.e. don't require installing redistributable packages or private/shared side-by-side assemblies)? How does one avoid using msvc[mpr]90.dll and just use the Windows API in \windows\system32*.{dll,sys}?
I'm thinking along the lines of the code that comes out of the demoscene, but that's frequently not made available.
Others have already responded with respect to linking CRT statically. If you also want a small binary at the same time, then your best bet is forego CRT entirely, and use only Win32 API functions as much as possible. You'll still get some CRT code, most notably related to startup (i.e. that which calls main) and shutdown (atexit handling etc), but otherwise the linker won't link CRT functions that you do not use.
You can avoid linking CRT altogether by using /Zl compiler switch. This means that main will no longer work, however - you'll need to define WinMain (name doesn't matter, but signature must match, and it must be __stdcall), and you will have to specify the name of your WinMain-like function as an entry point via linker /entry: switch. This will save you ~30Kb of CRT code (tested on a .cpp with an empty main).
If you go the latter route, you might also have to deal with issue of compiler intrinsics. There are some functions that are nominally defined by the CRT (and declared in its headers), but which are treated specially by the compiler, so that it inserts optimized assembly instructions at the point of the call where possible - examples are memset, strlen, and a good chunk of functions in <math.h>; a complete list can be found here. Since you don't have CRT, if you need these functions, or could avoid it but prefer the intrinsic because of improved performance (hard to do better than memset, for example), then you have to declare them yourself, and use #pragma intrinsic. E.g.:
// Contains macros and typedef only, so safe to include without CRT.
// We need it here for size_t.
#include <stddef.h>
extern "C"
{
int abs(int);
void* memset(void*, int, size_t);
}
#pragma intrinsic(abs, memset)
int __stdcall main(void*, void*, char*, int)
{
char tmp[10];
memset(tmp, abs(-123), 10);
return 0;
}
The above can be compiled with:
cl /c /Zl foo.cpp
link /entry:main foo.obj
Link the CRT statically via the /MT switch (and likewise MFC, if you're using it).
Static linking limits what you can do with DLLs somewhat, but for simple executables it works like a charm. (And if you're shipping DLLs, you can always ship private assemblies anyway.)
Use the static CRT. This doesn't create a dependency on msvc*.dll. The CRT is linked directly into your program. This doesn't create dependencies, but does increase the size of your executable.
More info on different CRT options here.
Statically link the runtime. MS Visual C++ has option /MT for that (default is /MD)
I think one way to do this is to just not use Visual Studio and instead rely on the command line SDK tools. (You can alternatively figure out how to config VS to do what you want, but that seems harder.) E.g.:
cl /c app.cpp
link app.obj ws2_32.lib

Resources