简体   繁体   English

Windows 说 64 位可执行文件是“不受支持的 16 位应用程序”

[英]Windows says 64-bit executable is "Unsupported 16-Bit Application"

I have a C++ program that links Google's WebRTC library that compiles and runs successfully when I target 32-bit but doesn't work at all when I target 64-bit.我有一个 C++ 程序,它链接 Google 的 WebRTC 库,当我以 32 位为目标时编译并成功运行,但当我以 64 位为目标时根本不起作用。 After some trial and error I created the following program:经过一些试验和错误,我创建了以下程序:

#include <media/base/adapted_video_track_source.h>

class AdaptedVideoTrackSource : rtc::AdaptedVideoTrackSource
{
public:
  void AddRef() const {}
  rtc::RefCountReleaseStatus Release() const { return rtc::RefCountReleaseStatus::kDroppedLastRef; }
  bool is_screencast() const {return false;}
  absl::optional<bool> needs_denoising() const {return false;}
  bool GetStats(webrtc::VideoTrackSourceInterface::Stats* stats) {return false;}
  webrtc::MediaSourceInterface::SourceState state() const {return webrtc::MediaSourceInterface::kLive;}
  bool remote() const {return false;}
};

int main() {
  AdaptedVideoTrackSource source;
}

This program fails with this error:该程序失败并出现以下错误: 在此处输入图片说明 If I remove the super class the program runs fine.如果我删除超类,程序运行良好。

How exactly do I debug a problem like this?我究竟如何调试这样的问题? I'm at a loss since I can't exactly debug the program.我不知所措,因为我无法完全调试程序。 dumpbin appears to think my webrtc library is fine but says warning LNK4048: Invalid format file; ignored dumpbin 似乎认为我的 webrtc 库很好,但说warning LNK4048: Invalid format file; ignored warning LNK4048: Invalid format file; ignored for my executable. warning LNK4048: Invalid format file; ignored我的可执行文件。

There's a lot of steps in the build process and I don't think I can put all of them here.构建过程中有很多步骤,我认为我无法将所有步骤都放在这里。 I use CMake with ExternalProject_Add to download and build webrtc.我使用带有 ExternalProject_Add 的 CMake 来下载和构建 webrtc。 I generate Ninja makefiles to build my code.我生成 Ninja 生成文件来构建我的代码。 Here are the ninja rules used to link the exe.以下是用于链接 exe 的忍者规则。

rule CXX_EXECUTABLE_LINKER__Test
  command = cmd.exe /C "$PRE_LINK && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=$OBJECT_DIR --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x64\mt.exe --manifests $MANIFESTS -- C:\PROGRA~2\MIB055~1\2017\COMMUN~1\VC\Tools\MSVC\1416~1.270\bin\Hostx64\x64\link.exe /nologo $in  /out:$TARGET_FILE /implib:$TARGET_IMPLIB /pdb:$TARGET_PDB /version:0.0  $LINK_FLAGS $LINK_PATH $LINK_LIBRARIES && $POST_BUILD"
  description = Linking CXX executable $TARGET_FILE
  restat = $RESTAT

build utest\Test.exe: CXX_EXECUTABLE_LINKER__Test utest\CMakeFiles\Test.dir\main.cpp.obj | <OTHER LIBARIES> || <OTHER LIBARIES>
  FLAGS = /DWIN32 /D_WINDOWS /GR /EHsc /bigobj /Zi /Ob0 /Od /RTC1 -MTd
  LINK_FLAGS = /machine:x64 /debug /INCREMENTAL /subsystem:console
  LINK_LIBRARIES = <OTHER LIBARIES> webrtc_bundle.lib <OTHER LIBRARIES>
  LINK_PATH = -LIBPATH:D:\Folder\install64\lib
  OBJECT_DIR = utest\CMakeFiles\Test.dir
  POST_BUILD = cd .
  PRE_LINK = cd .
  TARGET_COMPILE_PDB = utest\CMakeFiles\Test.dir\
  TARGET_FILE = utest\Test.exe
  TARGET_IMPLIB = utest\Test.lib
  TARGET_PDB = utest\Test.pdb

It's private code so I renamed the executable I build and replaced the non webrtc libraries with <OTHER LIBARIES> .这是私有代码,所以我重命名了我构建的可执行文件,并用<OTHER LIBARIES>替换了非 webrtc 库。

This is the args.gn I use to build webrtc:这是我用来构建 webrtc 的 args.gn:

target_cpu="x64"
rtc_enable_protobuf=true
is_official_build=false
rtc_build_examples=false
rtc_include_tests=false
enable_iterator_debugging=true
is_clang=false

Also, I wrote my own BUILD.gn file to bundle webrtc with other libraries that Google's build system can build.此外,我编写了自己的 BUILD.gn 文件,将 webrtc 与 Google 的构建系统可以构建的其他库捆绑在一起。

UPDATE更新

I found that I can manually link my obj files and make a perfectly good exe.我发现我可以手动链接我的 obj 文件并制作一个非常好的 exe。 Then I started going into the Ninja Makefiles generated by CMake and playing around with the linker rules.然后我开始进入由 CMake 生成的 Ninja Makefile 并尝试使用链接器规则。 I found that if I remove /debug from the linker flags then everything works great.我发现如果我从链接器标志中删除/debug ,那么一切都很好。 Of course, I want to be able to debug my debug builds.当然,我希望能够调试我的调试版本。

I moved on and tried to start building my project with clang-cl and lld-link which provided a little more diagnostic output.我继续前进并尝试使用 clang-cl 和 lld-link 开始构建我的项目,这提供了更多的诊断输出。 I started getting warnings about linking different versions of the run time library.我开始收到有关链接不同版本的运行时库的警告。 MSVC_RUNTIME_LIBRARY was correctly set and I had the /MTd flag in CMAKE_CXX_FLAGS and CMAKE_LINKER_FLAGS but by running ninja with the verbose setting I could see that my flags were being followed by /MDd which overwrote the previous runtime setting. MSVC_RUNTIME_LIBRARY 设置正确,我在 CMAKE_CXX_FLAGS 和 CMAKE_LINKER_FLAGS 中有 /MTd 标志,但是通过使用详细设置运行 ninja,我可以看到我的标志后面是 /MDd,它覆盖了以前的运行时设置。 Eventually I appended /MTd to CMAKE_CXX_FLAGS_DEBUG and CMAKE_CXX_FLAGS_RELEASE and now it's the last runtime flag in the compiler and link commands and I haven't had this problem since.最终我将 /MTd 附加到 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_CXX_FLAGS_RELEASE ,现在它是编译器和链接命令中的最后一个运行时标志,从那以后我就没有遇到过这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM