I saw in the definition of a socket in msdn the following:
SOCKET WSAAPI socket(
__in int af,
__in int type,
__in int protocol
);
What is the prefix "__in" mean?
and what is WSAAPI ?
__in (and friends) specify the intended use of each parameter, so that calls to that function may be mechanically checked.
See http://msdn.microsoft.com/en-us/library/aa383701(v=vs.85).aspx on how to activate the checking.
http://msdn.microsoft.com/en-us/library/ms235402.aspx describes the modern alternative.
WSAAPI expands to the calling convention used for the socket library functions. This ensures that the code for calls to the functions are generated correctly, even if the calling code is set to build with a different calling convention.
It is a preprocessor macro that is defined as nothing. The purpose is to declare the interface so that the user of the interface knows the purpose of function arguments (in terms of input/output parameters).
WSAAPI is the name for Microsoft's socket API. It is based on Berkeley sockets.
For those looking to find the calling convention so they can call WSAAPI functions from another language, WSAAPI is defined in Winsock2.h as:
#define WSAAPI FAR PASCAL
Then in minwindef.h:
#define FAR far
#define far
#if (!defined(_MAC)) && ((_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED))
#define pascal __stdcall
#else
#define pascal
#endif
#ifdef _MAC
#ifdef _68K_
#define PASCAL __pascal
#else
#define PASCAL
#endif
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define PASCAL __stdcall
#else
#define PASCAL pascal
#endif
An _MSC_VER of 800 is Visual C++ 1.0, which is ancient.
So it looks like if you're writing Mac code and _68K_ is defined, you get the __pascal calling convention. If you're using Visual C++ >= 1.0 and developing for Windows, it's the __stdcall calling convention. Otherwise, it's either __stdcall or nothing, depending on whether _STDCALL_SUPPORTED is defined.
So basically WSAAPI probably evaluates to __stdcall on your machine.
Related
I'm working on an existing c++ project with visual studio, and I found out that almost every function declaration gets a __cdecl in front of the function name, like:void __cdecl functionName(). Then I jump to the definition of __cdecl, which locates in the winnt.h file:
#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define NTAPI __stdcall
#else
#define _cdecl
#define __cdecl
#define NTAPI
#endif
I've searched cdecl and got that it's the default calling convention for C and C++ programs, but code above tells me that __cdecl extends to nothing. So why place a __cdecl before function name as it's just nothing ? or did I misunderstand the code above?
what's the meaning of #define __cdecl”
Lines that begin with # are preprocessor directives. #define is a directive that defines a preprocessor macro. #define __cdecl defines a macro with identifier __cdecl and empty replacement. If such macro is defined, the processor will replace all instances of the __cdecl with an empty string.
So why place a __cdecl before function name as it's just nothing ?
Take a look at the directives at the beginning of the definition in question:
#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#else
The macro is defined conditionally. When the macro is not defined, __cdecl will not expand to nothing. When not expanded to nothing, __cdecl is a microsoft specific function specifier as you have discovered.
The conditionally defined macro allows one to write code that uses __cdecl on systems that allow it, and automatically remove it on systems that do not.
But I'm still confused with the #if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) line, what does it mean?
It is a preprocessor directive that test whether the macro _MSC_VER has greater value than 800, or if macro _STDCALL_SUPPORTED is defined. If the test is false, then the code between #if and #else is removed. If it is true, then the code between #else and #endif is removed.
It means that if an API is defined as using NTAPI it will generate code that uses the __stdcall calling convention - a variation of the Pascal calling convention in which the callee cleans the stack. With __cdecl, the caller cleans the stack (so it supports variadic type functions).
And all of this is conditional on the #if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
I found several lines of code in this header FTD2XX that seem to have function signatures with three return types. How do I interpret this? Here is an example
FTD2XX_API
FT_STATUS WINAPI FT_Read(
FT_HANDLE ftHandle,
LPVOID lpBuffer,
DWORD nBufferSize,
LPDWORD lpBytesReturned
);
All help is much appreciated.
The actual return type is just FT_STATUS by itself:
typedef ULONG FT_STATUS;
FTD2XX_API is a macro that defines DLL import/export handling using __declspec directives:
#ifdef FTD2XX_EXPORTS
#define FTD2XX_API __declspec(dllexport)
#else
#define FTD2XX_API __declspec(dllimport)
#endif
When the API is being compiled into a DLL, FTD2XX_EXPORTS is defined so the DLL functions are exported. When the API is being consumed, FTD2XX_EXPORTS is not defined, so the DLL functions are imported.
WINAPI is a macro in windef.h that resolves to a calling convention (__stdcall on Windows systems):
#ifdef _MAC
...
#define WINAPI CDECL
...
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
...
#define WINAPI __stdcall
...
#else
...
#define WINAPI
...
#endif
So, your example function declaration would resolve to this (including parameter type resolutions as well):
__declspec(dllimport)
unsigned long __stdcall FT_Read(
void *ftHandle,
void *lpBuffer,
unsigned long nBufferSize,
unsigned long *lpBytesReturned
);
These types of macros are not uncommon in APIs that are meant to be used across multiple compilers, and/or compiled into DLLs. In this case, exported functions need to be declared differently in the implementation vs the usage, and also depending on the target platform and even the compiler used (for instance, some compilers use extern/__export instead of __declspec(dllimport)/__declspec(dllexport)).
I was taking a look at the PnP Configuration Manager functions and saw that each begins with these three macros:
CMAPI CONFIGRET WINAPI
I had to dig inside CfgMgr32.h to find CMAPI, which is defined as:
#if !defined (_CFGMGR32_)
#define CMAPI DECLSPEC_IMPORT
#else
#define CMAPI
#endif
According to Tim Roberts' article on DLL's in Kernel Mode, this allows functions with CMAPI to be either loaded at run-time or link-time. And we already know that WINAPI is just a macro for a calling convention.
But what about CONFIGRET? From CfgMgr32.h, it is defined as:
//
// Standardized Return Value data type
//
typedef _Return_type_success_(return == 0) DWORD RETURN_TYPE;
typedef RETURN_TYPE CONFIGRET;
I've never seen this before, what does this mean? What is the return type of these functions?
The underlying data type for CONFIGRET is a DWORD, as defined in CfgMgr32.h:
//
// Standardized Return Value data type
//
typedef _Return_type_success_(return == 0) DWORD RETURN_TYPE;
typedef RETURN_TYPE CONFIGRET;
CONFIGRET is an alias for RETURN_TYPE, and RETURN_TYPE an alias for a DWORD with additional semantic information attached by means of SAL annotations (SAL annotations are used by static code analyzers).
Annotating Function Behavior contains detailed information on this particular annotation:
_Return_type_success_(expr)
May be applied to a typedef. Indicates that all functions that return that type and do not explicitly have _Success_ are annotated as if they had _Success_(expr). _Return_type_success_ cannot be used on a function or a function pointer typedef.
The CMAPI preprocessor symbol defined in CfgMgr32.h as
#if !defined (_CFGMGR32_)
#define CMAPI DECLSPEC_IMPORT
#else
#define CMAPI
#endif
serves a different purpose, than what you proposed: It allows the same header file to be used for the consumer and producer of the library. The producer defines the _CFGMGR32_ preprocessor symbol, and provides the function definitions. The consumer doesn't define the _CFGMGR32_ preprocessor symbol, and CMAPI expands to an import specifier (__declspec(dllimport), defined in ntdef.h). This is used for Load-Time Dynamic Linking (vs. Run-Time Dynamic Linking). It is not used for static linking at all.
First of all I am using Mingw 4.8 as the compiler of the C++ DLL in Code:blocks 13.12 and Lazarus 1.4.2 for working with the pascal code.(windows 7)
I need to generete a dll in c++ or c that can be called from a pascal program.
The problem is that my knowlegde about pascal is null, It dosn't look really complicate to make a simple program but I can't find good information about how to import and use a C/C++ DLL.
The only thing that moreless worked was this: http://www.drbob42.com/delphi/headconv.htm
My real code:
Pascal:
funtion hello():Integer; external 'function' index 1;
...
Label1.Caption:=IntToStr(hello());
C++ DLL header:
#ifndef function_H
#define function_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILDING_DLL
#define FUNCTION_DLL __declspec(dllexport)
#else
#define FUNCTION_DLL __declspec(dllimport)
#endif
int __stdcall FUNCTION_DLL hello( );
#ifdef __cplusplus
}
#endif
#endif
C++ file:
#include <stdio.h>
#include "function.h"
__stdcall int hello( )
{
return 8;
}
But when try to pass any argument or do something complicated with the function,starts to give randoms numbers.
This is the new code:
Pascal:
function function1(t1:Integer):Integer; external 'function' index 1;
...
entero:=8;
Label1.Caption:=IntToStr(function1(entero2));
Also I update the c++ code to this:
C++:
#include <stdio.h>
#include "function.h"
__stdcall int function1(int t1)
{
return t1*2;
}
Header:
#ifndef funtion_H
#define funtion_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILDING_DLL
#define FUNCTION_DLL __declspec(dllexport)
#else
#define FUNCTION_DLL __declspec(dllimport)
#endif
int __stdcall FUNCTION_DLL function1(int t1);
#ifdef __cplusplus
}
#endif
#endif
I aslo read this other info:http://www.jrsoftware.org/ishelp/index.php?topic=scriptdll. And tried to implement the dll call like this:
Pascal:
function function1(t1: Integer): Integer; external 'function1#files:function.dll';
But I receive an error saying that:
The procedure entry point function1 could not be located in the
dynamic link library function.dll
I'm looking for an example that works or a online tutorial or something to continue working because I am very stuck with this.
Thank you in advance.
You need to make the calling conventions match. Your C++ code uses __stdcall. The Pascal code does not specify a calling convention and so defaults to register.
Declare the Pascal import like this:
function function1(t1:Integer):Integer; stdcall; external 'function' index 1;
Are you quite sure that you need to use an index when importing? It is much more common to import by name than by ordinal. I'd expect to see the import looking like this:
function function1(t1:Integer):Integer; stdcall; external 'function';
The reason why the function with no parameters succeeds is that for a parameterless function, the differences between calling convention do not matter. Once you start passing an argument, stdcall means that the argument is passed via the stack, and register means it is passed in a register. This mismatch explains the behaviour you observe.
Anyone knows what header I must include for the use of InetNtop function ?
I tried winsock2.h, ws2tcpip.h and i've include the Ws2_32 librabry. I am using windows 7
This is my error that i get an compile time: InetNtop : function could not be resolved
edit:
char temp[10];
int bytes_recv = Recv(temp, sizeof(temp));
char result[INET_ADDRSTRLEN];
InetNtop(AF_INET, (void*)(&temp[4]), result, sizeof(result));
I am trying to print an IP what is in temp.
Not 100% relevant, but for the linux/unix version of this call (inet_ntop(...)), you need to #include <arpa/inet.h>.
According to its documentation Ws2tcpip.h is its actual header file.
EDIT:
According to the documentation, using this function requires your code to be compiled for Windows Vista or later. Since you are including the necessary header and yet the function is not visible, I surmise the you have not set the proper defines or compiler options to compile your code for a suitable version.
The actual Windows version that you are using is not important - what you are compiling for (i.e. the target version) is.
EDIT 2:
You should add the proper #define directive as described here to indicate which Windows version you are compiling for. E.g.
#include <SdkDdkver.h>
#define NTDDI_VERSION NTDDI_VISTA
#define WINVER _WIN32_WINNT_VISTA
#define _WIN32_WINNT _WIN32_WINNT_VISTA
Some of these defines overlap and may not be needed, but on the rare times that I code for Windows I just use them all to make sure :-)
EDIT 3:
Things are a bit different for MinGW/GCC:
#include <w32api.h>
#define WINVER WindowsVista
#define _WIN32_WINDOWS WindowsVista
#define _WIN32_WINNT WindowsVista
Note: These defines should be placed before including Windows.h or any other header but w32api.h.
EDIT 4:
From the WS2tcpip.h in Visual Studio 2010:
#if (NTDDI_VERSION >= NTDDI_VISTA)
.
.
.
PCSTR
WSAAPI
inet_ntop(
__in INT Family,
__in PVOID pAddr,
__out_ecount(StringBufSize) PSTR pStringBuf,
__in size_t StringBufSize
);
PCWSTR
WSAAPI
InetNtopW(
__in INT Family,
__in PVOID pAddr,
__out_ecount(StringBufSize) PWSTR pStringBuf,
__in size_t StringBufSize
);
#define InetPtonA inet_pton
#define InetNtopA inet_ntop
#ifdef UNICODE
#define InetPton InetPtonW
#define InetNtop InetNtopW
#else
#define InetPton InetPtonA
#define InetNtop InetNtopA
#endif
.
.
.
#endif // (NTDDI_VERSION >= NTDDI_VISTA)
Therefore the critical define in this case is NTDDI_VERSION, as expected for a new API addition.
I cannot find the InetNtop definition in MinGW32/GCC-4.4.2, so it's quite possible that it is not supported in your version either.
Although it exists in Ws2tcpip.h, the default target for most projects is Windows XP, and the function you are trying to use was introduced in Vista, so, you need to configure your project to target Vista instead. There are at least three things you can do here:
In your stdafx.h (if you have one), find the definitions of WINVER and _WIN32_WINNT [by default these are both 0x0501], change them both to 0x0600. Windows 7 is 0x0601. Also, define NTDDI_VERSION to 0x06000000.
If you don't have a stdafx.h header, add these definitions to your project's C/C++ preprocessor settings (WINVER=0x0600,_WIN32_WINNT=0x0600,NTDDI_VERSION=0x06000000).
As a last resort, define these manually before including any headers for that particular source file:
#ifndef WINVER
#define WINVER 0x0600
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#ifndef NTDDI_VERSION
#define NTDDI_VERSION 0x06000000
#endif
#include <windows.h>
#include <Ws2tcpip.h>
Also, make sure you have an up-to-date copy of ws2tcpip.h. For example, the copy that comes with Visual Studio 2005 does not have a declaration for InetNtop.
Declare this function explicitly in your code.
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
{
struct sockaddr_storage ss;
unsigned long s = size;
ZeroMemory(&ss, sizeof(ss));
ss.ss_family = af;
switch(af) {
case AF_INET:
((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
break;
case AF_INET6:
((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src;
break;
default:
return NULL;
}
/* cannot direclty use &size because of strict aliasing rules */
return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)?
dst : NULL;
}
Looks like Ws2tcpip.h, see msdn.