使用PInvoke接口C / C ++ DLL时,调试断言失败

时间:2015-01-12 03:54:47

标签: c# c++ c dll pinvoke

我有一个C / C ++ DLL并试图使用PInvoke与C#应用程序连接。 我收到Debug assertion failed错误。当与C ++应用程序接口时,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;
}

错误信息如附图所示。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");
        }
    }
}

编辑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 个答案:

答案 0 :(得分:2)

你没有显示你的p / invoke声明,但你有100%的机会弄错了,因为没有正确的声明。这些函数不能直接从C#调用,因为它们的签名是C ++特有的。

调试断言跳闸是因为当C ++函数实际上不是一个时,它试图将其参数用作std::stringstd::string析构函数在作用域的末尾运行,尝试释放内存...并失败,因为std::string构造函数没有分配内存,因为没有{{ 1}}此处存在的对象

您可以添加一个包含某些p / invoke兼容字符串类型的包装器,例如std::stringconst char*,创建一个BSTR,然后调用实际函数。

事实上,您也无法从其他C ++编译器或版本中调用它。

相关问题