C# 试图读取或写入受保护的内存。C++;导入到C的dll# 0&&FindFileData.cFileName[0]!='。) { 如果(!isGoodForUs(directory+std::string(FindFileData.cFileName)))继续; 向后推(directory+std::string(FindFileData.cFileName)); } } } } CCOMSA(fileArray.size()); std::vector::const_迭代器it; int i=0; for(it=filesArray.begin();it!=filesArray.end();++it,++i) { a、 SetAt(i,A2BSTR_EX((*it).c_str()),FALSE); } 返回a.Detach(); }

C# 试图读取或写入受保护的内存。C++;导入到C的dll# 0&&FindFileData.cFileName[0]!='。) { 如果(!isGoodForUs(directory+std::string(FindFileData.cFileName)))继续; 向后推(directory+std::string(FindFileData.cFileName)); } } } } CCOMSA(fileArray.size()); std::vector::const_迭代器it; int i=0; for(it=filesArray.begin();it!=filesArray.end();++it,++i) { a、 SetAt(i,A2BSTR_EX((*it).c_str()),FALSE); } 返回a.Detach(); },c#,c++,C#,C++,当我通过C#调用dll时,我遇到了一个致命的异常: 试图读取或写入受保护的内存。这通常表示其他内存已损坏 电话如下: [DllImport("dlltest.dll")] [return: MarshalAs(UnmanagedType.SafeArray)] private extern static string[] getFiles(string directory, string fileFilter, bool recrusive); 以下是我的DLL源代码:

当我通过C#调用dll时,我遇到了一个致命的异常:

试图读取或写入受保护的内存。这通常表示其他内存已损坏

电话如下:

    [DllImport("dlltest.dll")]
    [return: MarshalAs(UnmanagedType.SafeArray)]
    private extern static string[] getFiles(string directory, string fileFilter, bool recrusive);
以下是我的DLL源代码:

extern "C" __declspec(dllexport) LPSAFEARRAY getFiles(string directory, std::string fileFilter, bool recrusive);

LPSAFEARRAY getFiles(string directory, std::string fileFilter, bool recrusive)
{
       std::vector<std::string> filesArray;

if (recrusive)
    getFilesByDirs(directory, fileFilter, false);

directory += "\\";

WIN32_FIND_DATAA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;

std::string filter = directory + (recrusive ? "*" : fileFilter);

hFind = FindFirstFileA(filter.c_str(), &FindFileData);

if (hFind == INVALID_HANDLE_VALUE)
{

}
else
{
    if (!recrusive)
    {
        if(isGoodForUs(directory + std::string(FindFileData.cFileName))) 
        {
            filesArray.push_back(directory + std::string(FindFileData.cFileName));
        }
    }

    while (FindNextFileA(hFind, &FindFileData) != 0)
    {
        if (!recrusive)
        {
            if(!isGoodForUs(directory + std::string(FindFileData.cFileName))) continue;
                filesArray.push_back(directory + std::string(FindFileData.cFileName));
        }
        else
        {
            if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)>0 && FindFileData.cFileName[0]!='.')
            {
                if(!isGoodForUs(directory + std::string(FindFileData.cFileName))) continue;
                    filesArray.push_back(directory + std::string(FindFileData.cFileName));
            }
        }
    }
}

CComSafeArray<BSTR> a(filesArray.size());

std::vector<std::string>::const_iterator it;
int i = 0;
for (it = filesArray.begin(); it != filesArray.end(); ++it, ++i)
{
    a.SetAt(i, A2BSTR_EX((*it).c_str()), FALSE);
}
return a.Detach();
}
extern“C”\uuu declspec(dllexport)LPSAFEARRAY getFiles(字符串目录,std::string fileFilter,bool recurusive);
LPSAFEARRAY getFiles(字符串目录,std::字符串文件过滤器,bool重新创建)
{
向量数组;
如果(再现)
getFileByDirs(目录,文件过滤器,false);
目录+=“\\”;
WIN32_FIND_DATAA FindFileData;
句柄hFind=无效的句柄值;
std::string filter=directory+(重新创建?*“:fileFilter);
hFind=FindFirstFileA(filter.c_str(),&FindFileData);
if(hFind==无效的句柄值)
{
}
其他的
{
如果(!重现)
{
if(isGoodForUs(目录+std::string(FindFileData.cFileName)))
{
向后推(directory+std::string(FindFileData.cFileName));
}
}
while(FindNextFileA(hFind和FindFileData)!=0)
{
如果(!重现)
{
如果(!isGoodForUs(directory+std::string(FindFileData.cFileName)))继续;
向后推(directory+std::string(FindFileData.cFileName));
}
其他的
{
if((FindFileData.dwFileAttributes和FILE_ATTRIBUTE_目录)>0&&FindFileData.cFileName[0]!='。)
{
如果(!isGoodForUs(directory+std::string(FindFileData.cFileName)))继续;
向后推(directory+std::string(FindFileData.cFileName));
}
}
}
}
CCOMSA(fileArray.size());
std::vector::const_迭代器it;
int i=0;
for(it=filesArray.begin();it!=filesArray.end();++it,++i)
{
a、 SetAt(i,A2BSTR_EX((*it).c_str()),FALSE);
}
返回a.Detach();
}

有人知道问题出在哪里吗?

真正的问题是,为什么不使用与GetFiles()调用等效的.Net方法

避免删除C++代码、额外的部署问题和在托管代码和非托管代码之间切换的执行惩罚。 编辑添加

<>当您想从C++中恢复您的C++ DLL时,最不痛苦的方法是创建一个C++包装类,使它尽可能简单。Microsoft建议通过您尝试使用的“平台调用”执行此操作(由于std::string类而遇到问题)

首先,请参阅本文,了解C#/C++互操作性的概述。第二,给出一个C++类包的快速例子。微软指的是在“只工作”的方法下使用C++包类。
在C和C++中做了很多跨平台编程,我必须祝你们好运,需要很多的努力才能使它正确。由于您显然使用C++作为跨平台互操作层,因此建议您为跨操作代码创建跨平台库(保持它与应用程序代码分开)。第二,尽可能多地为互操作创建外部C接口。这是真正的“通用”调用格式,没有名称损坏等问题。第二个问题是您需要多少互操作?基本文件和目录并不太难。套接字是另一组问题。多线程是另一种。我以前使用过,它一直是C++,已经存在很长时间了——但是它是一个非常强大的C++互操作库(除其他事项外)。< /P>你是否在调试器下运行它,以找出代码中的哪一行损坏了错误?@ TimoGueSuh yUp,当我通过Cype使用GETFrEX方法时,你不能封取C++ STL字符串。坚持使用LPCTSTR。对于使用SafeArray的返回类型是可以的,但我不确定封送处理程序是否会识别它。您可以尝试声明为返回类型对象,然后将其转换为String [],这样您就可以在调试器中检查封送器对数组的操作。还有一个缺少调用约定的情况,它是Cdecl。我的想法是在调制器平台中使用这个C++代码。当然,我需要为跨平台更改一些功能,但真正的原因是在其他平台上的使用。此外,我有很多C++代码连接到DLL的主要功能。因此,现在需要做大量的工作来改变C#方法。嗨@GaryWalker,由于在这个项目中的优先级和时间浪费,我将使用临时C#方法来进行此类操作。但现在我无法获取任何文件,结果为空。。您可以在编辑的帖子中看到代码,在上面^^您没有调用正确的方法。我提到的方法有3个参数,第三个参数允许指定递归描述,并在初始答案中添加了一些互操作建议
Directory.GetFiles Method (String path, String searchPattern, SearchOption searchOption)