使用 PInvoke 连接 C/C++ DLL 的调试断言失败

Debug assertion failed using PInvoke to interface C/C++ DLL

我有一个 C/C++ dll 并尝试使用 PInvoke 连接到 C# 应用程序。 我收到 Debug assertion failed 错误。该 dll 在与 C++ 应用程序接口时工作,问题仅在与 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;
}

错误信息如附图所示

我使用 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);
   }
}

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

调试断言失败,因为 C++ 函数试图将其参数用作 std::string,而实际上它不是一个。 std::string 析构函数在范围的末尾运行,试图释放内存...但失败了,因为 std::string 构造函数没有分配内存,因为 没有std::string 此处存在对象

您可以添加一个包装器,它接受一些 p/invoke 兼容的字符串类型,例如 const char*BSTR,创建一个 std::string,然后调用真正的函数.

事实上,从其他 C++ 编译器或版本调用它也会遇到问题。