Confused about Winsock2.dll vs Winsock2.h? - c++

I am a little confused, I am trying to make a program with no external dependencies (so it could be easily ported to UNIX for example) that has socket connection abilities. But I am unsure of what I should be using?
Is there a standard library on Windows XP, 7, 8 that can be linked against that can output a single exe that can run alone (not depend on a DLL to function)? For example on UNIX I can link against socket and use sys/socket.h and have like 95% of UNIX's without doing anything.

Same code just won't do for both. But you can use #ifdef WIN32 to make the preprocessor consider Windows stuff only when compiling under Windows.
In the headers:
#ifdef WIN32
// Windows exclusive dependencies go here
#include <windows.h>
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")
#define close(s) closesocket(s)
#else
// Linux exclusive dependencies go here
#include <sys/socket.h>
#endif
And inside main() you will need to do something like this:
#ifdef WIN32
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
I believe this is all, the rest of the API is widely compatible with the UNIX way of using sockets.

Related

C++/C: Migration from Make to Cmake (Windows and Linux): Platform specific implementations

I'm currently migrating a project of 2 million C++/C code lines from Makefiles to using Cmake. Most things are pretty straight forward, but I can't seem to find the best practice to achieve the following:
Many low level (legacy) components in my kernel library use compiler guards to differentiate between the Linux and Windows implementations in the following form:
#ifdef WINDOWS
// #include ...
#else
// #include ...
#endif
and/or:
void lowLevelFunction()
{
#ifdef WINDOWS
// Windows implementation
return;
#else
// Linux implementation
return;
#endif
}
Is there a best practice to do this on Cmake or to somehow delegate?
Thank you

How do is structure my files right, when I write code for linux and windows

I am currently not sure how I should seperate my code best. I currently programming a software which should run on Linux and Windows. So I decided to put all OS-secificstuff in thier own folder/files.
For example
This is the header file:
#ifdef __linux__
#include <unistd.h>
#elif _WIN64
#include <Windows.h>
#endif
#include <string>
#include <iostream>
#pragma once
class SystemTools
{
public:
// Delay in secounds until the programm continues
static void sleep(int delay);
private:
};
and the OS specific implementation is in the linux/windows folder
Linux:
#ifdef __linux__
#include "../SystemTools.h"
void SystemTools::sleep(int delay)
{
usleep(delay*1000000);
}
#endif
Windows:
#ifdef _WIN64
#include "../SystemTools.h"
void SystemTools::sleep(int delay)
{
Sleep(delay*1000);
}
#endif
This works and I have no problems so far, but when I now have methods which don´t need any OS specific code I created an additional folder "Generic" so I can write the code in there and don´t have to mantain the same code in the linux and windows file. For example like that:
Generic:
#include "../SystemTools.h"
void SystemTools::sleepMin(int delay)
{
sleep(delay*60);
}
#endif
That still workes on Linux but not on Windows (no error but does not compile, used codeblockes for that on windows). So how do I organize my code correct? Should I use only one file with ifdef even it that gets very fast ugly?
(compiler Linux: g++, Windows: should be MinGW)
Firstly I'd suggest you to use the most recent of C++ (C++20 or so) on your project. This way, we can abstract many OS related calls (like threading, synchronization, random numbers and etc).
That means, you won't really need to use too many of OS specific APIs. IE: C++11 and earlier already have a standard way to sleep:
https://en.cppreference.com/w/cpp/thread/sleep_for
In the end, if you really need to call OS specific things on windows and on linux, using a library could be interesting and pay attention that windows C++ compiler (visual studio) really like to use 'pre compiled headers' so, it's interesting to have a single header file where all windows specific headers can be included.
Basically that. You can have a standard Cmake or makefile for your linux build and use .sln Visual Studio project to build it to windows.
That's the way I would do that

How use 'fcntl' on Windows with and MinGW?

I'm trying to port a TCP application (specifically tcpsockets), however im getting this error:
error: 'fcntl' was not declared in this scope
I already wrote those includes
#ifdef WIN32
#define _WIN32_WINNT 0x0600 //enable
#include <Ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
typedef int socklen_t;
void close(int socket){closesocket(socket);}
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
Which solved most part of the references, however fcntl was not found.
How can I find a proper reference to it? Or naybe is there another windows method that could replace it?
fcntl() does not exist on Windows. For sockets, the equivalent function is ioctlsocket(). However, file controls on sockets in Linux are very different than in Windows, so not all of the fcntl() commands you are using may port to Windows, or may require different APIs.
Not sure why you are trying to use native sockets. But if there's no real reason, have a look at QTcpSocket instead. It's the Qt class for sockets and works on all platforms.

Can't find mkdir() function in dirent.h for windows

I am using dirent.h 1.20 (source) for windows in VC2013.
I can't find mkdir() in it.
How am I supposed to use it? Or can I create a directory somehow only using dirent.h?
simplest way that helped without using any other library is.
#if defined _MSC_VER
#include <direct.h>
#elif defined __GNUC__
#include <sys/types.h>
#include <sys/stat.h>
#endif
void createDir(string dir) {
#if defined _MSC_VER
_mkdir(dir.data());
#elif defined __GNUC__
mkdir(dir.data(), 0777);
#endif
}
Update: Since C++17, <filesystem> is the portable way to go. For earlier compilers, check out Boost.Filesystem.
The header you are linking to is effectively turning your (POSIX) dirent.h calls into (native) Windows calls. But dirent.h is about directory entries, i.e. reading directories, not creating ones.
If you want to create a directory (mkdir()), you need either:
A similar wrapping header turning your (POSIX) mkdir() call into the corresponding (native) Windows function calls (and I cannot point out such a header for you), or
use the Windows API directly, which might be pragmatic but would lead to a really ugly mix of POSIX and Windows functions...
// UGLY - these two don't belong in the same source...
#include <dirent.h>
#include <windows.h>
// ...
CreateDirectory( "D:\\TestDir", NULL );
// ...
Another solution would be to take a look at Cygwin, which provides a POSIX environment running on Windows, including Bash shell, GCC compiler toolchain, and a complete collection of POSIX headers like dirent.h, sys/stat.h, sys/types.h etc., allowing you to use the POSIX API consistently in your programming.
Visual Studio includes the <direct.h> header.
This header declares _mkdir and _wmkdir, which can be used to create a directory, and are part of the C libraries included with Visual Studio.
The other "easy" option would be to use Windows API calls as indicated by DevSolar.
You can use sys/types.h header file and use
mkdir(const char*) method to create a directory
Following is the sample code
#include<stdio.h>
#include<string.h>
#include <unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
int main()
{
if(!mkdir("C:mydir"))
{
printf("File created\n");
}
else
printf("Error\n");
}
mkdir is deprecated. Give #include <direct.h> as a header file. then write
_mkdir("C:/folder")

Visual studio C++: How to make parts of code not be seen by the windows compiler?

So jenerally I have small C++ project based on OpenSource crossplatform libs. So it probably would compile under linux. So I hited the point when I need to implement some defenatly platform specific class functions.
I have a class header with all functions declarations and cpp file with realisations. So first: how to declare my platform specific functions in header so when I'll try to compile under linux it will not try to compile windows specific ones... and when on windows compiler will not try to compile linux functions include headers etc.
So for windows I need some how wrap such super specific functions
HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
void DisplayDeviceInformation(IEnumMoniker *pEnum)
And some headers
#include <windows.h>
#include <dshow.h>
#pragma comment(lib, "strmiids")
While for linux I have such headers
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/videodev.h>
And I have function with name of void PrintCamerasList() which I wanna have one for bouth platfrms realisations for which I have seprate.
I hope you see what I need. So generally I need some example using my functions or once you can invent - let your imagination flow!)
So why do I need it all - I am creating some console app using OpenCV and I need to list user cameras names. OpenCV cannot do this on its own. so I asked how to do it for bouth platforms of my intrest - windows and linux
You want to look into platform specific macros and surround for example your MSVC specific code with some #ifdef _WIN32 / #endif pairs.
Take a look at http://predef.sourceforge.net/ for an extensive list of pre-defined macros various compilers provide to distinguish between operating systems, compilers, and processor architectures. They will allow you to distinguish between more than just Win32 and Linux if necessary.
Common practice is to use a compiler flag such as
#ifdef WIN_32
// Windows stuff...
#else
// Linux stuff
#endif
Check for the exact values of what windows flag is defined either in your compiler or in the headers you include