C ++ / CLI Dll с проблемой взаимодействия C # - PullRequest
5 голосов
/ 27 июня 2011

У меня есть 3 проекта в одном решении.

У меня есть:

  • родной C ++ dll,
  • a C # Winform,
  • и прокси C ++ / CLI без чистого режима для связи между двумя другими проектами (и использования встроенной функции в управляемом коде в C #)

Так что, когда я запускаю приложение, все работает. Но когда я нажимаю кнопку «Generer» в моей форме win, которая выполняет функцию NativeMethod :: Test () C ++ / CLI, она вылетает, и у меня появляется это всплывающее сообщение:

Необработанное исключение типа 'System.BadImageFormatException' произошло в System.Windows.Forms.dll

Дополнительная информация: не удалось загрузить файл или сборка 'EngineInterfaceWrapper.dll' или один из его зависимости. не все приложение Win32 валиде. (Исключение от HRESULT: 0x800700C1)

Когда я вхожу в проектные настройки в Conf. Свойства -> Linker -> Advanced: Target Machine, для него установлена ​​величина "MachineX86" для моей собственной C ++ собственной и управляемой DLL, и мой WinForm также находится в X86. Я устал от многих конфигураций, но это не работает.

Edit:

Возможно, проблема в заголовке "TradeEngine.h" "в заголовке C ++ / CLI: EngineInterfaceWrapper.h это будет работать, но если "#include" TradeEngine.h "" всегда находится в заголовке CLI, у меня будет та же ошибка. У вас есть идея?

Редактировать: - Решено -

Я наконец нашел проблему. Это библиотека повышения, названная в моем родном C ++ .h. Поскольку оболочка должна иметь собственный заголовок, она также связывает библиотеку Boost (даже с моей прагмой в коде, это странно), и Boost создает много проблем, когда вызывается в управляемом коде, поэтому я помещаю заголовки из собственного .h на родной .cpp и все работает. Спасибо всем за помощь.

код:

нативный C ++

TradeEngine.h

#ifdef TRADEENGINE_EXPORTS
#define SYMBOL_DECLSPEC __declspec(dllexport)
#define SYMBOL_DEF
#else
#define SYMBOL_DECLSPEC __declspec(dllimport)
#define SYMBOL_DEF      __declspec(dllimport)
#endif

#pragma managed(push, off)
#include <curl/curl.h>
#include <boost\filesystem.hpp>

#include <boost\tokenizer.hpp>
#include <boost\lexical_cast.hpp>
#include <boost\thread.hpp>
#pragma managed(pop)

EXTERN_C SYMBOL_DECLSPEC void __stdcall Test(void);

TradeEngine.cpp

SYMBOL_DECLSPEC void __stdcall Test(void)
{
}

C ++ / CLI

EngineInterfaceWrapper.h

#pragma once

#include "TradeEngine.h"

using namespace System;
using namespace System::Runtime::InteropServices;

namespace EngineInterfaceWrapper {

    public ref class NativeMethod
    {
    public:
        static void AjoutColonneDifferenceCourtClotureOuvertureReelle(void);
        static void Test();
    };
}

EngineInterfaceWrapper.cpp

#pragma region Includes
#include "stdafx.h"
#include "EngineInterfaceWrapper.h"
using namespace EngineInterfaceWrapper;

#include <msclr/marshal.h>
using namespace msclr::interop;
#pragma endregion

void NativeMethod::Test()
{
    ::Test();
}

C # Winform

Program.cs

namespace TradeInterface
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Form1.cs

generer_Click () - это событие, запускаемое кнопкой, когда пользователь нажимает на Generer.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Runtime.InteropServices;
using EngineInterfaceWrapper;

namespace TradeInterface
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void generer_Click(object sender, EventArgs e)
        {
            NativeMethod.Test();
        }
    }
}

Ответы [ 2 ]

8 голосов
/ 09 марта 2012

Я нашел решение:

http://marc.info/?l=boost-users&m=123425857320026

В Свойствах конфигурации -> C / C ++ -> Препроцессор -> Определения препроцессора добавьте BOOST_ALL_DYN_LINK для принудительного использованияиз DLL.Кроме того, скопируйте необходимые библиотеки DLL в каталог, где находится исполняемый файл.Например, скопируйте boost_thread-vc90-mt-gd-1_XX.dll в MyApp / bin / Debug.

4 голосов
/ 27 июня 2011

Одной из причин может быть то, что вы пытаетесь загрузить собственную 32-битную DLL в 64-битном процессе. Убедитесь, что в вашем приложении установлен целевой уровень платформы x86, чтобы приложение запускалось внутри WoW64.

...