Отладочное утверждение не удалось использовать PInvoke для взаимодействия с C / C ++ DLL

0

У меня есть C/C++ dll и пытаюсь взаимодействовать с С# -приложением, используя PInvoke. Я получил сообщение об ошибке "Ошибка Debug assertion failed. DLL работает при взаимодействии с приложением C++, проблема только в интерфейсе с приложением С#. Мои файлы DLL.h и.cpp

Файл заголовка

#include <string>
#include <fstream>
#include <iostream>

#ifdef DLL_EXPORTS
#define DLL_EXPORTS __declspec(dllexport) 
#else
#define DLL_EXPORTS __declspec(dllimport) 
#endif

#define   PASS              0
#define   FILECREATE_FAIL   1
#define   CAMERA_ERROR      2
#define   MAX_NUM_FRAMES    10000

using namespace std;

#ifdef __cplusplus
extern "C"
{
#endif

    // Returns pass  0
    //         Fails 1
    // Open the file at the path and start acquisition
    DLL_EXPORTS int start_acquisition(string path); 
    DLL_EXPORTS int stop_acquisition();

#ifdef __cplusplus
}
#endif

CPP файл

#include "stdafx.h"
#include "IntensityDll.h"
#include <sstream>


ofstream fileout;
int counter;
char Header[64];
short Image[MAX_NUM_FRAMES][6400]; 
int ret;
int acquisition();

int start_acquisition(std::string path)
{
        ret = PASS;
        try
        {
            fileout.open(path);//fstream
            if (fileout.is_open()) {                
                 ret = acquisition();
            }


        }
        catch(fstream::failure e)
        {
            cout << "Exception opening/reading file. " << endl;;
            return FILECREATE_FAIL;             
        }


    return ret;
}

Информация об ошибке показана на прилагаемом рисунке. Изображение 174551

Я использовал PInvoke, как следует

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;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("C:\\WindowsFormsApplication1\\WindowsFormsApplication1\\Wavelength_MaxIntensityDll.dll")]
        public static extern int start_acquisition(string path);
        [DllImport("C:\\WindowsFormsApplication1\\Wavelength_MaxIntensityDll.dll")]
        public static extern int stop_acquisition();
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int ret = start_acquisition("C:\\Users\\nyan2012\\Desktop\\Wavelength_test\\test1.txt");
        }
    }
}

EDIT 1: Я показываю пример использования PInvoke. Какая разница с моей?

class PlatformInvokeTest
{
   [DllImport("user32.dll")]
   public static extern int MessageBoxA(
      int h, string m, string c, int type);

   public static int Main() 
   {
      return MessageBoxA(0, "Hello World!", "My Message Box", 0);
   }
}
  • 1
    Тест __cplusplus в заголовочном файле абсолютно бесполезен, так как эти функции используют типы, которых нет в C.
  • 0
    Неуправляемая функция в вашем вопросе с использованием соглашения о вызовах cdecl. По умолчанию для p / invoke используется stdcall.
Теги:
dll
pinvoke

1 ответ

2
Лучший ответ

Вы не показывали свои объявления p/invoke, но у вас 100% шанс, что вы ошибаетесь, потому что нет правильного. Эти функции нельзя напрямую вызывать из С#, так как их подписи являются C++ -специфическими.

Утверждение отладки отключается, потому что функция C++ пытается использовать свой параметр как std::string когда это фактически не одно. std::string destructor работает в конце области действия, пытаясь освободить память... и терпит неудачу, потому что память не была выделена конструктором std::string, потому что нет объекта std::string здесь.

Вы можете добавить оболочку, которая принимает некоторый тип строки, совместимый с p/invoke, такой как const char* или BSTR, создает std::string, а затем вызывает реальные функции.

На самом деле вам также будет сложно вызвать его из других C++ компиляторов или версий.

  • 0
    Спасибо, я обновил свое приложение на C #.
  • 0
    Я обновил в EDIT 1. Я чувствую, что понимаю, что вы пытались объяснить. Но в соответствии с примером, который я обновил, в чем отличие от моего?
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню