3

Here is the relevent C# bits

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();
}

Here is the (relevant) C++ code:

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();

I am very much aware that System.BadImageFormatException can be thrown by DllImport if there's a build format mismatch (ie calling a 32 bit dll from a 64 bit application). However, this is not the case. Both are built and target the same CPU.

After doing some troubleshooting, I found that it's caused solely by the iostream and vector includes. By removing those includes, the error goes away and the calls work. In fact, I didn't have any problems until I started implementing code that needed those includes. However, I need those includes, and the better part of a day's worth of research has turned up no documentation or explanation for this bizarre behavior, and many examples in fact use iostream.

I'm using both Jetbrains Rider and Clion, if that is relevent.

  • *Both are built and target the same CPU* -- How did you determine this, i.e. what you finally end up with are actually 32-bit binaries? Also, [the answers here do not just talk about "bitness"](https://stackoverflow.com/questions/2728560/badimageformatexception-when-loading-32-bit-dll-target-is-x86) – PaulMcKenzie May 16 '18 at 00:25
  • For one, build targets are clearly observable in both IDE's I develop with, and, as an added measure, I used dumpbin to examine the file header of the dll. Also, as I already said in my question, removing includes of `iostream` and `vector` somehow the error goes away. That has nothing to do with build targets. – CrockettScience May 16 '18 at 00:33
  • I am aware that bitness is not the only cause of `System.BadImageFormatException`, and didn't intend to imply such. Clearly it's related to those includes, but I have not found documentation or leads as to what the problem actually is. – CrockettScience May 16 '18 at 00:39
  • Why not see if it has anything to do with using the runtime library? Using `vector` and `iostream` requires usage of the correct runtime library. That is one of the other answers given at the link. – PaulMcKenzie May 16 '18 at 00:40
  • Those answers were relating the fact that building a native dll in Visual Studio necessitates having VS runtime libraries attached, However I'm using Clion, specifically the MingW64 toolchain. Do I need to include some kind of dll for that runtime, and if so, how would I go about doing that? – CrockettScience May 16 '18 at 01:05
  • 1
    What are the dependencies for your C++ DLL? (I use Dependency Walker). Are any of them the Visual C++ runtime? If there are missing DLL's, the easiest thing is to place them in the same folder as your executable. – PaulMcKenzie May 16 '18 at 01:16
  • Got it. No VC dependencies (as expected) but I didn't realize Mingw64 has some of it's own dependency requirements. I got it all sorted out in dependency walker. I'll post the answer below. – CrockettScience May 16 '18 at 01:37

1 Answers1

0

Using Dependency Walker, I was missing 3 dll's:

  • libstdc++-6.dll
  • libgcc_s_seh-1.dll
  • and libwinpthread-1.dll

They are the required runtime libraries if you use the MingW environment. Dropping those into the executable folder did the trick. They can be found in {Your MingW/MingW64 installation folder}\bin

  • That was not the real problem, a missing DLL cannot cause a BadImageFormatException. You need to find the *other* copy (or copies) of those DLLs to get your machine fixed. Typically accidentally found through a messed-up PATH environment variable or a stray copy in the OS directory. Use the *where* command first. – Hans Passant May 16 '18 at 02:37
  • My PATH is set up for C++ development, But I'm treating it as release, ie most users do not have MingW64 with PATH pointing at the provided runtimes, so I need to provide those dll's. Hence why testing in the executable works but accessing bindings from it as a dll was failing. More on that here: https://stackoverflow.com/questions/18138635/mingw-exe-requires-a-few-gcc-dlls-regardless-of-the-code. – CrockettScience May 16 '18 at 04:06
  • 1
    Also it seems that there are cases where a missing DLL can cause a BadImageFormatException. See here for another case example https://stackoverflow.com/questions/2728560/badimageformatexception-when-loading-32-bit-dll-target-is-x86 – CrockettScience May 16 '18 at 04:06