System.AccessViolationException:试图在 C++ dll 中读取或写入受保护的内存

System.AccessViolationException : Attempted to read or write protected memory in C++ dll

所以我已经为此绞尽脑汁了一段时间。我构建了一个用于 VB.net 项目的 C++ dll。 C++源码如下所示

C++

    #include "stdafx.h"
    #include "mydll.h"
    #include <vector>
    #include <string>
    #include <algorithm>
    #include <sstream>
    #include <fstream>
extern "C" __declspec(dllexport) void __cdecl ExtractVolumeDataC(std::string path, std::string fileName, bool chkVol, std::string txtKeyName)
{

    std::string line;
    std::vector<std::vector<std::string>> ValuesCSV;
    std::replace(path.begin(), path.end(), '\', '/'); //replace backslash with forward slash
    std::ifstream in(path + fileName);
    while (std::getline(in, line)) {
    std::string phrase;
    std::vector<std::string> row;
    std::stringstream ss(line);
    while (std::getline(ss, phrase, ',')) {
    row.push_back(std::move(phrase));
    }
    ValuesCSV.push_back(std::move(row));
    }
}

我在VB.net中使用的代码如下

VB.net

    Public Class Form1

    <Runtime.InteropServices.DllImport("mydll.dll")> _
    Public Shared Sub ExtractVolumeDataC(ByVal path As String, ByVal fileName As String, ByVal txtKeyName As String)

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ExtractVolumeDataC("C:\users\me\documents\", "VOL.CSV", "01100872")
    End Sub
End Class

我观察到的一个问题是,我在使用基元时没有遇到此错误,但包括 stringvector 等 STL 元素。我得到了错误。如果这是一个愚蠢的问题,我很抱歉我已经 15 年没有看过 C++ 代码了。

VB.net 不将字符串作为 c++ std::string 传递,ByVal 字符串作为指向字符的指针传递(即旧的 C 样式字符串)。您可以使用 LPCSTR 作为参数类型。在您的情况下,这将是:

extern "C" __declspec(dllexport) void __cdecl ExtractVolumeDataC(LPCSTR path, LPCSTR fileName, bool chkVol, LPCSTR txtKeyName)

有关详细信息,请参阅 This Microsoft support page

不得在 dll 中使用 STL 元素。它们没有明确地从 dll 中导出。最好的方法是始终对 DLL 中的导出函数使用 C 样式代码。

这里是某人关于 dll 中使用的 STL 的回答。

returning std::string/std::list from dll