【发布时间】: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);