在 Unity 中使用 x64 c++ dll 给出 "Is not a valid Win32 application error"

Using x64 c++ dll in Unity gives "Is not a valid Win32 application error"

我想做什么

我正在尝试使用一些关于在 Unity 中使用 OpenCV 库的 Point Cloud Library (PCL) functionalities in Unity 64bits. To do so, I proceed like explained in this tutorial

我做了什么以及我遇到的问题

所以我安装了 PCL library (v1.8, x64), I linked it to a Visual Studio C++ project and got a simple function using it (the getting started example of the library)。

然后我将这个项目编译为 x64 版本 dll,我将其包含在 Unity 中的 Asset/Plugins 文件夹中,以及 PCL 版本 dll。

最后,我使用以下行统一加载 dll 并使 MySimpleFunction 可用于我的 C# 脚本。

[DllImport("PCLToolsForUnity")] 
internal static extern int MySimpleFunction();

问题是当我 运行 调用 MySimpleFunction() 的 C# 脚本时,Unity 显示以下错误:

Failed to load 'Assets/Plugins/PCLToolsForUnity.dll' with error '%1 is not a valid Win32 application.

我已经检查并尝试过的内容

我读到这可能是由于混合了 32 位和 64 位 dll 和应用程序引起的,但是我的 Unity 安装是 64 位以及我包含的 dll(我什至用 dumpbin /headers 命令检查过)。所以我什至不知道为什么 Unity 期望我的 dll 是 Win32 应用程序..

我还检查了 dll 的路径中没有 space,因为我读到它可能是导致此错误的另一个原因。

之前,我在一个不使用库的 C++ 项目中尝试了所有这些,并且效果很好。所以它可能是由链接库引起的

知道什么可能导致此错误以及如何解决它吗?


编辑

我在 x64 机器上工作。

经过多次测试,问题似乎是我的DLL本身。当我使用以下命令 运行 任何函数时:C:\Windows\SysWOW64\rundll32.exe PCLToolsForUnity.dll, testFunction,我得到与 Unity 中相同的错误:PCLToolsForUnity.dll is not a valid Win32 application.

我还找到了 "breaks" 我的 dll 的行。我导出的函数之一如下:

PCLTOOLSFORUNITY_API int pcdWrite(void)
{
pcl::PointCloud<pcl::PointXYZ> cloud;

// Fill in the cloud data
cloud.width = 5;
cloud.height = 1;
cloud.is_dense = false;
cloud.points.resize(cloud.width * cloud.height);

for (size_t i = 0; i < cloud.points.size(); ++i)
{
    cloud.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
    cloud.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
    cloud.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}

pcl::io::savePCDFileASCII("test_pcd.pcd", cloud);
std::cerr << "Saved " << cloud.points.size() << " data points to test_pcd.pcd." << std::endl;

for (size_t i = 0; i < cloud.points.size(); ++i)
    std::cerr << "    " << cloud.points[i].x << " " << cloud.points[i].y << " " << cloud.points[i].z << std::endl;

return (0);

}

我注意到如果我注释行 pcl::io::savePCDFileASCII("test_pcd.pcd", cloud); 并重新编译我的 dll,那么它就可以工作,我可以 运行 dll 的功能。在没有这一行的情况下编译 dll 时,我可以从中调用函数并且它正在运行。

我检查了链接到项目的库,对我来说似乎没问题,所以仍然不知道我的问题出在哪里。我希望这些新信息能有所帮助。

多亏了Dependancy Walker,我终于找到了原因。

实际上是链接错误的问题。 PCL 使用 OpenNi 库和链接到该库的 32 位版本而不是 64 位版本的变量路径。

对于看到此问题的未来用户,您还可以通过以下方式识别哪些 .dll 是 x86 与 x64: https://github.com/lucasg/Dependencies

此工具仍在维护中。

在我的例子中,这个错误来自我的 .dll 从操作系统的其他地方获取 32 位 Freetype 依赖项。只需将适当的 Freetype.dll 拖入我的自定义 .dll 即可解决该问题。