c_src\bcrypt_nif.c(94):错误 C2275:'ERL_NIF_TERM':非法使用此类型作为表达式

c_src\bcrypt_nif.c(94) : error C2275: 'ERL_NIF_TERM' : illegal use of this type as an expression

我想知道以前是否有人见过这个错误,如果有,可以采取什么措施。

C:\workspace\myproj>iex -S mix phx.server
==> bcrypt_elixir

Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

        del /Q /F priv
        erl -eval "io:format(\"~s~n\", [lists:concat([\"ERTS_INCLUDE_PATH=\", code:root_dir(), \"/erts-\", erlang:system_info(version), \"/include\"])])" -s init stop -noshell > Makefile.auto.win
        nmake /                   /F Makefile.win priv\bcrypt_nif.dll

Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

        if NOT EXIST "priv" mkdir "priv"
        cl /O2 /EHsc /I"c_src /std:c11" /I"c:/Program Files/erl10.7/erts-10.7/include" /LD /MD /Fepriv\bcrypt_nif.dll  c_src\bcrypt_nif.c c_src\blowfish.c
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

bcrypt_nif.c
c_src\bcrypt_nif.c(94) : error C2275: 'ERL_NIF_TERM' : illegal use of this type as an expression
        c:/Program Files/erl10.7/erts-10.7/include\erl_nif.h(100) : see declaration of 'ERL_NIF_TERM'
c_src\bcrypt_nif.c(94) : error C2146: syntax error : missing ';' before identifier 'output'
c_src\bcrypt_nif.c(94) : error C2065: 'output' : undeclared identifier
c_src\bcrypt_nif.c(95) : error C2143: syntax error : missing ';' before 'type'
c_src\bcrypt_nif.c(97) : error C2065: 'output_data' : undeclared identifier
c_src\bcrypt_nif.c(99) : error C2065: 'output' : undeclared identifier
c_src\bcrypt_nif.c(377) : error C2143: syntax error : missing ';' before 'volatile'
c_src\bcrypt_nif.c(379) : error C2065: 'ptr' : undeclared identifier
c_src\bcrypt_nif.c(379) : error C2100: illegal indirection
c_src\bcrypt_nif.c(379) : error C2106: '=' : left operand must be l-value
blowfish.c
Generating Code...
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\amd64\cl.EXE"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\amd64\nmake.EXE"' : return code '0x2'
Stop.
could not compile dependency :bcrypt_elixir, "mix compile" failed. You can recompile this dependency with "mix deps.compile bcrypt_elixir", update it with "mix deps.update bcrypt_elixir" or clean it with "mix deps.clean bcrypt_elixir"
==> orcasite
** (Mix) Could not compile with "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\nmake.exe" (exit status: 2).
One option is to install a recent version of
[Visual C++ Build Tools](http://landinghub.visualstudio.com/visual-cpp-build-tools)
either manually or using [Chocolatey](https://chocolatey.org/) -
`choco install VisualCppBuildTools`.

After installing Visual C++ Build Tools, look in the "Program Files (x86)"
directory and search for "Microsoft Visual Studio". Note down the full path
of the folder with the highest version number. Open the "run" command and
type in the following command (make sure that the path and version number
are correct):

    cmd /K "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64

This should open up a command prompt with the necessary environment variables
set, and from which you will be able to run the "mix compile", "mix deps.compile",
and "mix test" commands.

我尝试在 bcrypt Makefile.in 中更改编译器的 C 版本,但结果是一样的。

环境:

OS: Windows 10 专业版

二郎:10.7

长生不老药:1.10.3

Microsoft C/C++ 优化编译器版本:16.00.30319.01 for x64

bcrypt_elixir: 2.2.0

由于某种原因,C 编译器最终无法理解遵循 C99 标准的代码;特别是它不允许在函数中的第一条语句之后声明变量。

由于bcrypt_elixir有一个Makefile.win文件,提示之前在Windows上已经编译成功了,我不太明白为什么会这样,但无论如何你应该可以通过修改 bcrypt_nif.c 来解决这个问题,改变这个:

static ERL_NIF_TERM bcrypt_gensalt_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary csalt;
    unsigned int log_rounds, minor;

    if (argc != 3 || !enif_inspect_binary(env, argv[0], &csalt) ||
            csalt.size != BCRYPT_MAXSALT ||
            !enif_get_uint(env, argv[1], &log_rounds) ||
            !enif_get_uint(env, argv[2], &minor))
        return enif_make_badarg(env);

    ERL_NIF_TERM output;
    unsigned char *output_data = enif_make_new_binary(env, BCRYPT_SALTSPACE, &output);

    bcrypt_initsalt(log_rounds, (uint8_t *)csalt.data, (char *)output_data, (uint8_t)minor);

    return output;
}

对此:

static ERL_NIF_TERM bcrypt_gensalt_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary csalt;
    unsigned int log_rounds, minor;
    /* added these two lines */
    ERL_NIF_TERM output;
    unsigned char *output_data;

    if (argc != 3 || !enif_inspect_binary(env, argv[0], &csalt) ||
            csalt.size != BCRYPT_MAXSALT ||
            !enif_get_uint(env, argv[1], &log_rounds) ||
            !enif_get_uint(env, argv[2], &minor))
        return enif_make_badarg(env);

    /* removed one line, and modified this line: */
    output_data = enif_make_new_binary(env, BCRYPT_SALTSPACE, &output);

    bcrypt_initsalt(log_rounds, (uint8_t *)csalt.data, (char *)output_data, (uint8_t)minor);

    return output;
}

可能还有其他地方需要进行类似的更改。