【问题标题】:error LNK2019: unresolved external symbol __imp____acrt_iob_func referenced in function _printf in VS2019错误 LNK2019:在 VS2019 中的函数 _printf 中引用了无法解析的外部符号 __imp____acrt_iob_func
【发布时间】:2020-11-13 23:37:33
【问题描述】:

我正在使用 Visual Studio 2019 社区版,我正在尝试从 C 程序运行汇编函数。

我收到以下错误:

  Rebuild started...
    1>------ Rebuild All started: Project: ArrayReverser, Configuration: Debug Win32 ------
    1>Assembling GetValueFromASM.asm...
    1>ArrayReverser.cpp
    1>ArrayReverser.obj : error LNK2019: unresolved external symbol __imp__srand referenced in function _main
    1>ArrayReverser.obj : error LNK2019: unresolved external symbol __imp__rand referenced in function _main
    1>ArrayReverser.obj : error LNK2019: unresolved external symbol __imp____acrt_iob_func referenced in function _printf
    1>ArrayReverser.obj : error LNK2019: unresolved external symbol __imp____stdio_common_vfprintf referenced in function __vfprintf_l
    1>C:\Users\firas\source\repos\ArrayReverser\Debug\ArrayReverser.exe : fatal error LNK1120: 4 unresolved externals
    1>Done building project "ArrayReverser.vcxproj" -- FAILED.
    ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

我已经尝试了几乎所有可以在互联网上找到的解决方案,但都没有奏效,我希望有人能提供有关正在发生的事情的见解。

这是 C 代码:

#include <iostream>
#include <stdlib.h>



extern "C" void GetValueFromASM(int* y, const int *x, int n);


int main(int argc, char* argv[])
{
    const int n = 10;
    int x[n], y[n];
    srand(41);
        for (int i = 0; i < n; i++)
            x[i] = rand() % 1000;
        GetValueFromASM(y, x, n);


printf("\n---------------Array Reverser-------------\n");
        for (int i = 0; i < n; i++)
        {
            printf("i:     %5d       y: %5d         x: %5d\n", i, y[i], x[i]);
        }

        return 0;
}  
    

这是汇编代码:

.386 
.model flat,c
.code 
 GetValueFromASM  PROC
               push ebp  ;we pushed the register ebp onto the stack
               mov  ebp,esp  
               push esi
               push edi
               
               xor  eax,eax
               ;now we load the parameters (int* y, const int* x, int n) onto edi,esi,ecx
               mov  edi,[ebp+8]  ;bp - stack base Pointer Register 
               mov  esi,[ebp+12]
               mov  ecx,[ebp+16] 
               
               
               ; in order to reverse the array elemtns we use the following command
               lea esi,[esi+ecx*4-4] 
               pushfd
               std
               
    @@:        lodsd 
               mov [edi], eax
               add  edi, 4
               dec  ecx
               jnz @B
               
               popfd
               mov eax,1
               
               
               ;Epilouge
               pop edi
               pop esi
               pop ebp
     
    GetValueFromASM endp
end     

链接到我的项目文件: https://drive.google.com/file/d/1entjG8nHarDTW0AEmvKhv0Cvrw9v0BF2/view?usp=sharing

【问题讨论】:

  • 确保您也拥有#include &lt;stdio.h&gt;。你在链接legacy_stdio_definitions.lib吗?如果您删除程序集,您的项目是否编译?看起来 stdio 的东西只从 C 中使用,所以程序集只是噪音,不是问题的一部分。
  • 对于 MSVC 配置,尝试每个解决方案通常不是一个好主意。事实上,应该非常小心,不要改变任何你不知道效果的东西。现在可能值得创建一个新项目。
  • @Jester 我包含了那个库,没有任何改变。
  • @MichaelPetch 我做到了。不幸的是,它仍然无法正常工作。

标签: assembly visual-c++ x86 linker masm


【解决方案1】:

我下载了您的项目并观察到类似的链接器错误(实际上我有更多错误)。我查看了项目的所有链接器选项,并注意了粗体的条目。粗体的选项没有被继承。最引人注目的是Entrypoint

您使用 MASM 函数 Reverser 覆盖了默认的 C 启动入口点。我修改了EntryPoint,使其为 blank(将其删除)。当我重建项目时,不再出现链接器错误。

您的Reverser 函数最后没有ret,因此它在运行时会抛出异常。我在Reverser 函数的底部添加了一个ret 并运行代码并得到以下输出:


注意:@rustyx 有非常好的建议“对于 MSVC 配置,尝试每个解决方案通常都是一个坏主意。事实上,应该非常小心,不要改变任何你不知道效果如何。现在可能值得创建一个新的项目。" .如果您创建一个全新的 CONSOLE 项目并且不修改入口点应该没有问题。

【讨论】:

  • 你猜为什么听起来像运行时问题的东西会导致链接器错误?
  • @Jester :我粗略看了一眼。几乎就像假设是,如果您更改入口点,您将不再对 C 运行时感兴趣。删除入口点只会为入口点添加额外的选项,既不会添加到链接器选项(我比较了它们之间的整个命令行),也不会添加到 C/C++ 编译器选项。这似乎是链接器的一些行为。
猜你喜欢
  • 2013-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 2013-12-18
相关资源
最近更新 更多