mingw64 pjsip sizeof(fd_set)始终是sizeof(pj_fd_set_t)的两倍,从而导致sock_select.c中的断言

时间:2019-06-27 14:43:29

标签: c windows mingw pjsip msys2

我已经将pjsip编译到我在msys2 / mingw环境(64位)中编写的程序中。它编译良好。但是,当我在程序中运行它时,会得到一个断言

// Line 49 of ../src/pj/sock_select.c
sizeof(pj_fd_set_t)-sizeof(pj_sock_t)>=sizeof(fd_set)

每次我运行程序。

当我进行一些挖掘时,人们会谈论增加PJ_IOQUEUE_MAX_HANDLES。所以我做了,我在断言之前将printf放在函数中,以查看大小是什么:

// My PJ_FD_ZERO variant
PJ_DEF(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp)
{
    printf( "PJ_IOQUEUE_MAX_HANDLES: %d, pj_fd_set_t: %I64d, pj_sock_t: %I64d, fd_set: %I64d\n", PJ_IOQUEUE_MAX_HANDLES, sizeof(pj_fd_set_t), sizeof(pj_sock_t), sizeof(fd_set) );
    PJ_CHECK_STACK();
    pj_assert(sizeof(pj_fd_set_t)-sizeof(pj_sock_t) >= sizeof(fd_set));

    FD_ZERO(PART_FDSET(fdsetp));
    PART_COUNT(fdsetp) = 0;
}

程序将输出如下内容:

10:27:43.477        os_core_win32.c !pjlib 2.9 for win32 initialized
10:27:43.507         sip_endpoint.c  .Creating endpoint instance...
PJ_IOQUEUE_MAX_HANDLES: 16384, pj_fd_set_t: 65552, pj_sock_t: 4, fd_set: 131080

但是,当我调整PJ_IOQUEUE_MAX_HANDLES时,pj_fd_set_t的大小会按需增加 ,但是!无论sizeof(pj_fd_set_t)是多少,sizeof(fd_set)也会比DOUBLE略小! Winsock指南说我不能设置fd_set的大小,所以我很困惑如何设置大小!我在pjsip代码中的任何地方都看不到该设置。

因此,调整PJ_IOQUEUE_MAX_HANDLES无疑是一场失败的战斗。

如何解决此问题,以便我的代码停止声明?

一些参考

我运行以配置pjsip的Bash脚本

#!/bin/bash

JOPT=1
DEBUG=false
BUILD_ALL=true
CLEAN_BEFORE_BUILD=false

TOUCH_COMMAND="touch configure.ac aclocal.m4 configure Makefile.am Makefile.in"

while getopts ":pdj:o:c" opt; do
        case $opt in
                j)
                        JOPT="$OPTARG"
                        ;;
                c)
                        echo "Clean before build is set."
                        CLEAN_BEFORE_BUILD=true;
                        ;;
                d)
                        DEBUG=true
                        ;;
                o)
                        IFS=', ' read -r -a BUILD_OPTS <<< "${OPTARG}"
                        BUILD_ALL=false

                        for option in "${BUILD_OPTS[@]}" ; do
                                # Set individual
                                case $option in
                                        pjsip)
                                                BUILD_PJSIP=true;
                                                ;;
                                        *)
                                                echo "Unknown build option ${option}"
                                                exit
                                esac
                        done
                        ;;
                \?)
                        echo "Invalid option: -${OPTARG}" >&2
                        exit 1
                        ;;
                :)
                        echo "Option -${OPTARG} requires an argument." >&2
                        exit 1
                        ;;
        esac
done

# Make the out
mkdir out
OUT_PREFIX="$( pwd )/out"
export PKG_CONFIG_PATH="${OUT_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}"

if [ "$DEBUG" = true ] ; then
MAKEFLAGS="-g -O0"
else
MAKEFLAGS="-O2"
fi

# Main directory
LIB_DIRECTORY="$(pwd)/lib"

# Descend
cd "${LIB_DIRECTORY}"

pwd

# pjsip
cd "${LIB_DIRECTORY}/pjsip"
if [ "${BUILD_ALL}" = true ] || [ "${BUILD_PJSIP}" = true ] ; then
        eval $TOUCH_COMMAND

        ./configure CFLAGS="${MAKEFLAGS} -I${OUT_PREFIX}/include" CXXFLAGS="${MAKEFLAGS}" LDFLAGS="-L${OUT_PREFIX}/lib" \
                --prefix="${OUT_PREFIX}" \
                --disable-openh264 \
                --disable-v4l2 \
                --disable-ffmpeg \
                --enable-libsamplerate \
                --disable-video \
                --enable-shared \
                --disable-static \
                --disable-libyuv \
                --with-external-speex \
                --with-gnutls \
                || exit

        if [ "${CLEAN_BEFORE_BUILD}" = true ] ; then
                make clean
        fi

        # Without this it breaks on msys2
        make -j $JOPT dep || exit
        # Make the actual
        make -j $JOPT || exit
        # Note, had issue with writing to //c/.../pkgconfig/libproject.pc
        make install || exit
fi

断言屏幕截图

assert screenshot

-编辑-

运行此程序时,很有趣,它的sizeof(fd_set)是520。

#include <winsock.h>

#include <iostream>

int main( int argc, char *argv[] )
{
    std::cout <<
        "sizeof( fd_set )=" << sizeof( fd_set ) << "\n"
        "FD_SETSIZE=" << FD_SETSIZE << std::endl;

    return( EXIT_SUCCESS );
}

结果:

sizeof( fd_set )=520
FD_SETSIZE=64

1 个答案:

答案 0 :(得分:0)

我又是那个家伙,回答我自己的问题。

我想这是怎么回事,尽管pjsip在configure上被检测到,但并未检测到我正在使用mingw使用Windows。

checking build system type... x86_64-w64-mingw32
checking host system type... x86_64-w64-mingw32
checking target system type... x86_64-w64-mingw32

我在类型中找到了这个小块。h

/** Socket handle. */
#if defined(PJ_WIN64) && PJ_WIN64!=0
    typedef pj_int64_t pj_sock_t;
#else
    typedef long pj_sock_t;
#endif

我认为已经意识到,如果大小不大,pj_fd_set_t(由pj_sock_t组成)将始终小于fd_set(由fd组成)。那将解释比例现象。这也是因为检测到PJSIP在Windows上定义了FD_SETSIZE。

所以我像上面一样运行./configure然后手动修改:

  • build.mak
  • build / os-auto.mak

用PJ_WIN32 = 1替换PJ_AUTOCONF = 1。

然后我手动修改了Makefile,明确地包含了正确的文件。

include build/os-win32.mak

然后我使用make dep && make && make install

进行编译

最后,当我将其编译到程序中时,它抱怨实现unicode字符串函数,因此我查看了该文件是否抛出错误(pj / compat / string.h)。我找到了#if定义的行(_MSC_VER),并添加了一些其他定义,以支持MINGW宏。

#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
#   define strcasecmp   _stricmp
#   define strncasecmp  _strnicmp
#   define snprintf     _snprintf
#   define vsnprintf    _vsnprintf
#   define snwprintf    _snwprintf
#   define wcsicmp      _wcsicmp
#   define wcsnicmp     _wcsnicmp
#else
#   define stricmp      strcasecmp
#   define strnicmp     strncasecmp

#   if defined(PJ_NATIVE_STRING_IS_UNICODE) && PJ_NATIVE_STRING_IS_UNICODE!=0
#       error "Implement Unicode string functions"
#   endif
#endif

然后它起作用了!