BadImageFormatException: Попытка использовать файл C ++ DLL в C#? - PullRequest
1 голос
/ 28 января 2020

Win32 C ++ DLL проект сохраняется в моем файле bin / Debug вместе с другими DLL.

Запуск режима отладки x86 в моем C# проекте.

Из предыдущих попыток решить эту проблему Я изменил конфигурацию сборки на x86 с x64, но все равно получаю ту же ошибку.

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

Я создал проект DLL в Visual studio. Это мой основной код 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;

}

Я получаю это сообщение об ошибке, которое я не понимаю:

Исключение: «System.BadImageFormatException» в ComputerToArduino.exe An Произошло необработанное исключение типа «System.BadImageFormatException» в ComputerToArduino.exe. Была предпринята попытка загрузить программу с неверным форматом. (Исключение из 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).

Ошибка после добавления extern к функции C ++:

Помощник по управляемой отладке 'PInvokeStackImbalance': 'Вызов функции PInvoke' ComputerToArduino! ComputerToArduino.Form1 :: AddNumber 'разбалансировал стек. Вероятно, это связано с тем, что управляемая подпись PInvoke не соответствует неуправляемой целевой подписи. Убедитесь, что соглашение о вызовах и параметры подписи PInvoke соответствуют целевой неуправляемой подписи. '

1 Ответ

1 голос
/ 29 января 2020

В x86 (в отличие от x64) существуют разные соглашения о вызовах. Язык C (и extern "C" в C ++) по умолчанию соответствует соглашению о вызовах cdecl , тогда как C# по умолчанию соответствует соглашению о вызовах stdcall . Поэтому вы должны установить соглашение о вызовах cdecl в C#, например:

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