Ошибка связывания при построении без встроенных функций CRT, memcpy и memset

Я пытаюсь создать приложение как можно меньше, и при этом я пытаюсь избежать использования CRT, используя вызовы win API вместо стандартных вызовов C/C++. К сожалению, я все еще получаю одну ошибку компоновщика:

Error   2   error LNK2001: unresolved external symbol _memcpy

Я не вызываю memcpy нигде в моем коде, поэтому я предполагаю, что одна из функций Windows вызывает его. Включение внутренних функций дает неразрешенный символ _memset, который я тоже не использую. Из моего понимания, как memcpy, так и memset должны быть включены встроенные функции включены. Поскольку мой код слишком длинный для публикации, вот вызовы win API в моей программе:

  • lstrcpy
  • wsprintf
  • CopyMemory-ошибка переключается на _memset, когда я комментирую это
  • OpenFileMapping
  • MapViewOfFile
  • CreateFileMapping

мои вопросы:

  • почему внутренние функции не включены, если у меня есть /Oi объявлено?
  • мне нужно объявить memset и memcpy самостоятельно?
    • если да, то как это сделать без жалоб Visual Studio на переопределение внутренних функций?

3 ответов


/Oi не документируется как обязательная вставка всех встроенных компонентов, где это возможно, вместо этого он просто дает компилятору возможность сделать это. Я не смог понять, какую логику MSVC использует для достижения окончательного вывода, но некоторые факторы включают режим проекта (гораздо более вероятно, что он будет вводить встроенные компоненты в RELEASE по сравнению с DEBUG) и длину ваших функций.

последние версии Visual Studio действительно интегрировали зависимости MSVCRT в компилятор, и становится все труднее генерировать код, который не зависит от стандартной среды выполнения C.

стандартный способ работы вокруг этих вопросов (хотя очень посмотрел на Microsoft), чтобы связать с системной копией MSVCRT.dll, который поставляется в той или иной форме со всеми версиями Windows. Пока вы используете стандартные функции C, такие как memset вы можете громко игнорировать пронзительные взгляды Microsoft неодобрение и ссылка на содержание вашего сердца, но не пытайтесь использовать его для более сложных функций и API, предоставляемых CRT.

для связи с msvcrt.dll вам нужно будет либо использовать LoadLibrary и co или использовать предварительно сгенерированный msvcrt.lib (Microsoft намеренно не предоставляет его), чтобы сообщить MSVC, какие функции доступны в системе MSCRT.dll файлы


memset() приедет из ZeroMemory()

при нажатии на это я просто набрал канонические определения memcpy, memmove, memset из "языка программирования C".


вы не можете избежать ссылки на CRT. Однако, чтобы уменьшить размер вашего EXE, вы можете ссылаться на CRT статически. Компоновщик удалит весь ненужный код CRT, поэтому ваше приложение будет как можно меньше. И ошибок компоновщика не будет.