2015-01-12 3 views
0

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

Заголовок файла

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

Информационный ошибка, как показано на прилагаемой картинке. enter image description here

Я использовал 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. –

ответ

2

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

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

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

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

+0

Спасибо, я обновил свое приложение C#. – batuman

+0

Я обновил EDIT 1. Я чувствую, что понимаю, что вы пытались объяснить. Но в соответствии с примером, который я обновил, какая разница от моей? – batuman

+0

Разница заключается в том, что [функция MessageBoxA использует 'const char *'] (http://msdn.microsoft.com/en-us/library/ms645505%28VS.85%29.aspx) не C++ 'std :: string '. В C# нет ничего, что может вызвать функцию, которая использует параметр 'std :: string'. –

Смежные вопросы