【发布时间】:2018-10-25 21:48:36
【问题描述】:
这里是相关的 C# 位
KrautVK.cs
internal static class KrautVK{
[DllImport("lib\\krautvk", CallingConvention = CallingConvention.Cdecl, EntryPoint = "init")]
internal static extern int Init(int width, int height, string title, bool fullscreen);
[DllImport("lib\\krautvk", CallingConvention = CallingConvention.Cdecl, EntryPoint = "windowShouldClose")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool WindowShouldClose();
[DllImport("lib\\krautvk", CallingConvention = CallingConvention.Cdecl, EntryPoint = "pollEvents")]
internal static extern void PollEvents();
[DllImport("lib\\krautvk", CallingConvention = CallingConvention.Cdecl, EntryPoint = "terminate")]
internal static extern void Terminate();
}
这是(相关的)C++ 代码:
KrautVK.h
#ifndef KRAUTVK_H_
#define KRAUTVK_H_
#include <cstdio>
#include <vector>
#include <iostream>
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#define EXPORT extern "C" __declspec(dllexport)
...
EXPORT int init(int w, int h, char *title, int f);
EXPORT int windowShouldClose();
EXPORT void pollEvents();
EXPORT void terminate();
我非常清楚,如果构建格式不匹配(即从 64 位应用程序调用 32 位 dll),DllImport 可能会抛出 System.BadImageFormatException。然而,这种情况并非如此。两者都是针对同一个 CPU 构建的。
在做了一些故障排除后,我发现它完全是由 iostream 和 vector 包含引起的。通过删除这些包含,错误消失并且调用工作。事实上,在我开始实现需要这些包含的代码之前,我没有遇到任何问题。但是,我需要这些内容,而且一天的研究中大部分都没有找到任何文件或解释这种奇怪的行为,事实上许多例子都使用iostream。
如果相关的话,我同时使用 Jetbrains Rider 和 Clion。
【问题讨论】:
-
两者都是构建并针对相同的 CPU -- 你是如何确定这一点的,即你最终得到的实际上是 32 位二进制文件?另外,the answers here do not just talk about "bitness"
-
首先,在我开发的两个 IDE 中都可以清楚地观察到构建目标,并且作为一项附加措施,我使用了 dumpbin 来检查 dll 的文件头。另外,正如我在问题中已经说过的那样,删除包含
iostream和vector的错误以某种方式消失了。这与构建目标无关。 -
我知道位不是
System.BadImageFormatException的唯一原因,并且不打算暗示这样。显然它与那些包含有关,但我还没有找到文档或导致问题实际是什么。 -
为什么不看看它是否与使用运行时库有关?使用
vector和iostream需要使用正确的运行时库。这是链接中给出的其他答案之一。 -
C++ DLL 的依赖项是什么? (我使用 Dependency Walker)。它们中的任何一个都是 Visual C++ 运行时吗?如果缺少 DLL,最简单的方法是将它们放在与可执行文件相同的文件夹中。