【问题标题】:BadImageFormatException: Attempting to use a C++ DLL file in C#?BadImageFormatException:试图在 C# 中使用 C++ DLL 文件?
【发布时间】:2020-01-28 17:18:53
【问题描述】:

Win32 C++ DLL 项目与其他 DLL 一起保存在我的 bin/Debug 文件中。

在我的 C# 项目上运行 Debug x86 模式。

从以前解决此问题的尝试中,我已将构建配置从 x64 更改为 x86,但仍然收到相同的错误。

namespace ComputerToArduino
{
    public partial class Form1 : Form

    {

        [DllImport("MySimpleLib.dll", CharSet = CharSet.Unicode)]
        public static extern int AddNumber(int a, int b);

        public Form1()
        {
            InitializeComponent();
            disableControlsArduino();
            disableControlsMotor();
            getAvailableComPorts();
            chartInit();

            int result = AddNumber(1, 2);
            Console.Write(result);
        }
    }
}

我在 Visual Studio 中创建了一个 DLL 项目。这是我的主要 DLL 代码:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
extern "C" __declspec(dllexport) int AddNumber(int n1, int n2);


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

int AddNumber(int n1, int n2)
{

    return n1 + n2;

}

我收到了这个我不明白的错误信息:

抛出异常:ComputerToArduino.exe 中的“System.BadImageFormatException” ComputerToArduino.exe 中出现“System.BadImageFormatException”类型的未处理异常 试图加载格式不正确的程序。 (HRESULT 异常:0x8007000B)

'ComputerToArduino.exe' (CLR v4.0.30319: ComputerToArduino.exe): 加载'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Remote Debugger\x64\Runtime\Microsoft .VisualStudio.Debugger.Runtime.dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 程序“[14748] ComputerToArduino.exe”已退出,代码为 -1 (0xffffffff)。

将外部添加到 C++ 函数后出错:

托管调试助手“PInvokeStackImbalance”:“调用 PInvoke 函数“ComputerToArduino!ComputerToArduino.Form1::AddNumber”使堆栈失衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。'

【问题讨论】:

  • 能否请您 edit 提出基于类似 BadImageFormatException 帖子的调查结果的问题?
  • @AlexeiLevenkov 添加。在这篇文章之后,我将平台目标更改为 x86,但我仍然遇到同样的问题:stackoverflow.com/questions/30183232/…
  • 您将 DLL 编译为 32 位还是 64 位?如果 dll 是 c++,那么 AddNumber 很可能被破坏了,您应该添加 extern "C" {}。
  • @Neil 我相信 32。我只是在 Visual Studio 中使用默认的 DLL 项目,所以我相信 32 位。添加外部“C”后出现 PInvoke 错误。我真的不知道发生了什么。
  • 在 x86 中(与 x64 不同),有不同的调用约定。我相信语言 C(和外部“C”)默认为 __cdecl 调用约定。你可能想试试__stdcall,像这样:extern "C" __stdcall __declspec(dllexport) int AddNumber(int n1, int n2);

标签: c# c++ dll x86


【解决方案1】:

在 x86 中(与 x64 相比),有不同的调用约定。语言 C(和 C++ 中的外部“C”)默认为 cdecl 调用约定,而 C# 默认为 stdcall 调用约定。因此,您必须在 C# 中将调用约定设置为 cdecl,如下所示:

[DllImport("MySimpleLib.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public static extern int AddNumber(int a, int b);

【讨论】:

    猜你喜欢
    • 2017-11-13
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 2023-04-07
    相关资源
    最近更新 更多