C#调用C++编译生成的dll时,抛出BadImageFormatException异常

目录

一、问题:

二、试验环境:

2.1、创建一个“动态链接库(DLL)”的C++项目:

2.2、C++项目的配置:

2.3、C++项目的源代码:

2.4、创建一个“控制台应用(.NET Framework)”的C#项目:

2.5、C#项目的配置:

2.6、C#项目的源代码:

三、结论:

C++为32位:最后生成的dll所在目录为“\Debug”

C++为64位:最后生成的dll所在目录为“\x64\Debug”

四、参考文档:


一、问题:

        C++代码编译生成dll后,由C#代码(生成exe)调用这个非托管的dll,运行时抛出BadImageFormatException(试图加载格式不正确的程序)异常。

        参考各文档,基本上都是说,因为dll的位数与exe的位数不一致导致的,所以以下试验,验证dll的位数与exe的位数应该如何搭配。

二、试验环境:

2.1、创建一个“动态链接库(DLL)”的C++项目:

2.2、C++项目的配置:

        采用默认配置即可。

        对于C++项目,通过“配置管理器”->“活动解决方案平台”,以及“项目上下文”->“平台”,可以切换x86(32位)、x64(64位)。

2.3、C++项目的源代码:

        红框中的代码,是创建“动态链接库(DLL)”的C++项目时,默认的代码。绿框中的代码,是新建的代码,从HelloWorldCpp.dll导出TestHelloWorld函数,供HelloWorldCpp.dll的调用者使用。

//HelloWorld.cpp

#include "pch.h"
#include <iostream>

using namespace std;

extern "C" _declspec(dllexport) void TestHelloWorld() {
    cout << "Hello World!" << endl;

    return;
}

2.4、创建一个“控制台应用(.NET Framework)”的C#项目:

2.5、C#项目的配置:

        “生成”->“目标平台”,决定了由C#代码编译生成的exe的位数。“生成”->“配置”/“平台”,对exe的位数没有影响,但决定了生成的dll所在的目录。

         当“目标平台”“Any CPU”时,“首选32位”可以被勾选。

        对于C#项目,通过“配置管理器”->“活动解决方案平台”,以及“项目上下文”->“平台”,可以切换AnyCPU、x86(32位)、x64(64位)。

2.6、C#项目的源代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace UseHelloWorldDll
{
    class Program
    {
        static void Main(string[] args)
        {
            TestHelloWorld();

            return;
        }

        [DllImport("HelloWorldCpp.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern unsafe void TestHelloWorld();
    }
}

三、结论:64位Win10+VS2019

C++为32位:最后生成的dll所在目录为“\Debug”

1、C++平台为32位,C#平台为32位/目标平台为32位。成功

2、C++平台为32位,C#平台为32位/目标平台为64位。试图加载格式不正确的程序

3、C++平台为32位,C#平台为32位/目标平台为Any Cpu,且首选32位。成功

4、C++平台为32位,C#平台为32位/目标平台为Any Cpu,且无首选32位。试图加载格式不正确的程序

注意:C#平台为32位,最后生成的exe所在目录为“\bin\x86\Debug”;而目标平台决定了exe的位数。

5、C++平台为32位,C#平台为64位/目标平台为32位。成功

6、C++平台为32位,C#平台为64位/目标平台为64位。试图加载格式不正确的程序

7、C++平台为32位,C#平台为64位/目标平台为Any Cpu,且首选32位。成功

8、C++平台为32位,C#平台为64位/目标平台为Any Cpu,且无首选32位。试图加载格式不正确的程序

注意:C#平台为64位,最后生成的exe所在目录为“\bin\x64\Debug”;而目标平台决定了exe的位数。

9、C++平台为32位,C#平台为Any Cpu/目标平台为32位。成功

10、C++平台为32位,C#平台为Any Cpu/目标平台为64位。试图加载格式不正确的程序

11、C++平台为32位,C#平台为Any Cpu/目标平台为Any Cpu,且首选32位。成功

12、C++平台为32位,C#平台为Any Cpu/目标平台为Any Cpu,且无首选32位。试图加载格式不正确的程序

注意:C#平台为Any Cpu,最后生成的exe所在目录为“\bin\Debug”;而目标平台决定了exe的位数。

C++为64位:最后生成的dll所在目录为“\x64\Debug”

1、C++平台为64位,C#平台为32位/目标平台为32位。试图加载格式不正确的程序

2、C++平台为64位,C#平台为32位/目标平台为64位。成功

3、C++平台为64位,C#平台为32位/目标平台为Any Cpu,且首选32位。试图加载格式不正确的程序

4、C++平台为64位,C#平台为32位/目标平台为Any Cpu,且无首选32位。成功

5、C++平台为64位,C#平台为64位/目标平台为32位。试图加载格式不正确的程序

6、C++平台为64位,C#平台为64位/目标平台为64位。成功

7、C++平台为64位,C#平台为64位/目标平台为Any Cpu,且首选32位。试图加载格式不正确的程序

8、C++平台为64位,C#平台为64位/目标平台为Any Cpu,且无首选32位。成功

9、C++平台为64位,C#平台为Any Cpu/目标平台为32位。试图加载格式不正确的程序

10、C++平台为64位,C#平台为Any Cpu/目标平台为64位。成功

11、C++平台为64位,C#平台为Any Cpu/目标平台为Any Cpu,且首选32位。试图加载格式不正确的程序

12、C++平台为64位,C#平台为Any Cpu/目标平台为Any Cpu,且无首选32位。成功

四、参考文档:

C#目标平台×86、×64、Any CPU的区别_柚柚同学_YY的博客-CSDN博客_any cpu

C#工程 平台和目标平台区别_一顿操作猛如虎,啥也不是!的博客-CSDN博客

编译c#项目,在项目属性中,平台与目标平台的区别是什么?_鹧鸪菜的博客-CSDN博客

C#基础教程(十三) VS平台与目标平台_c# 配置管理器_yangwenxue1989的博客-CSDN博客

C#程序调用C++动态库(dll文件)遇到的坑_小言_互联网的博客_wya1

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值