C# 从dll调用函数时分配大小无效

C# 从dll调用函数时分配大小无效,c#,c++,dll,visual-studio-2013,marshalling,C#,C++,Dll,Visual Studio 2013,Marshalling,我刚开始使用dll,但我以前没有遇到过这个问题,所以它可能没有dll连接。我有C++中实现的KMP字符串匹配算法,我用DLL调用它。p> 这是我的出口: extern "C" __declspec (dllexport) const char* naive(const char* text, const char* str); extern "C" __declspec (dllexport) const char* KMP(const char* text, const char* str

我刚开始使用dll,但我以前没有遇到过这个问题,所以它可能没有dll连接。我有C++中实现的KMP字符串匹配算法,我用DLL调用它。p> 这是我的出口:

extern "C" __declspec (dllexport) const char* naive(const char* text, const   char* str);
extern "C" __declspec (dllexport) const char* KMP(const char* text, const char* str);
我的进口:

 [DllImport(@"dll_path", CallingConvention = CallingConvention.Cdecl)]
 public static extern IntPtr KMP([MarshalAs(UnmanagedType.LPStr)] string text, [MarshalAs(UnmanagedType.LPStr)] string str);
从c呼叫#

和C++函数:

const char* KMP(const char* text, const char* str)
{
    int tL = strlen(text);
    int sL = strlen(str);
    /* Algorithm */
 }
const char* KMP(const char* text, const char* str)
{
    int tL = strlen(text);
    int sL = strlen(str);
    string match = "";

    if (sL == 0 || tL == 0)
        throw "both text and string must be larger than 0";
    else if (sL > tL)
        throw "the text must be longer than the string";

    int tI = 0;
    int col = 0, row = 0;

    while (tI <= tL - sL)
    {
        int i = 0;
        int tmpCol = -1;
        int next = 1;
        for (; i <= sL && text[i + tI] != '\0'; i++)
        {
            if (text[i + tI] == '\n')
            {
                row++;
                tmpCol++;
            }
            if (text[i + tI] == str[0] && next == 1 && i > 0)
                next = i;

            if (text[i + tI] != str[i])
                break;
        }
        if (i == sL)
        {
            match += to_string(row) + ',' + to_string(col) + ';';
        }

        tI += next;

        col = tmpCol > -1 ? tmpCol : col + next;
    }
    char* c = new char[match.length() - 1];
    c[match.length() - 1] = '\0';
    for (int i = 0; i < match.length() - 1; i++)
        c[i] = match[i];
    return c;
}
调用函数后立即引发异常。所以我想这不是代码实现。有线的事情是,只有在第二个参数(str)中有一个“\n”新行时才会抛出它,不管它确切在哪里。如果没有新线路,它将正常运行。最让我困惑的是为什么只有第二个参数,它们的声明和使用是相同的。我还实现了Naive算法,同样的故事

我找到的所有答案都是当数组或未声明变量的大小为负数时,指针上却没有。但我怀疑这有什么相似之处,因为当我的搜索字符串(第二个参数(str))不包含新行时,代码会正常执行

有什么想法吗

前面谢谢你

编辑(函数体):

const char*KMP(const char*text,const char*str)
{
int tL=strlen(文本);
int sL=strlen(str);
字符串匹配=”;
如果(sL==0 | | tL==0)
抛出“文本和字符串都必须大于0”;
else if(sL>tL)
抛出“文本必须比字符串长”;
int tI=0;
int col=0,row=0;
while(tI-1?tmpCol:col+next;
}
char*c=新字符[match.length()-1];
c[match.length()-1]='\0';
对于(int i=0;i
只需更改代码以处理不匹配的情况,因为运行时无法分配
0-1=0xfffffffffff
字节。现在我还更改了复制缓冲区分配和循环代码以避免覆盖(正如@HenkHoltermann所指出的):

。。。
if(match.length()==0)
返回“无匹配项”;
//为除最后分号以外的所有字符+\0分配
char*c=新字符[match.length()];
c[match.length()-1]='\0';
//复制除最后分号以外的所有字符
对于(int i=0;i
!它仍然不会复制最后一个分号,因此如果需要,则必须在缓冲区中再添加一个符号


p.S.:我还发现您的代码有一些问题:

  • 使用C++异常。CLR将捕获它们作为SEH(因为VC++使用SEH),总体上还不是一个好主意-< /LI>
  • 使用带符号的
    int
    表示长度
    int tL=strlen(text);
    strlen
    返回无符号的
    size\u t
    。这可能不是实际问题,但也不是正确的方法

  • <代码> ITPTR < /代码>,我们的教授建议我们分配,因为我们刚开始使用DLL,并且告诉我们字符串数组会导致很多问题,最好使用这个“模板”。释放…我完全忘记我在一段时间内还没有使用C++。分配是这个代码> char *c=新char [匹配。长度()- 1 ]。;
    为什么
    const char*
    /
    IntPtr
    返回类型?该算法不应该返回字符串中的索引(
    int
    )KMP是的,MU函数返回所有与行和列索引匹配的匹配项。当它在输入中确实依赖于<代码> \n <代码>时,C++代码中存在某种bug。由于超文本/缺少代码> \r>代码>,您可能在缓冲区之外编写。@ VEILY13 13,您尝试了完全存根方法(如<代码>…{return“adfadsf”})?只是为了绝对确保这是封送问题。danm…我一定监督过这一点…因为我认为我的输入匹配…似乎不匹配。非常感谢您解决了这一问题。在我的辩护中,我测试了word\n,但它不是匹配的(如我所想)因为它是word\n xD。无论如何,非常感谢!谢谢你的提示,我会继续的。再次感谢。@veili_13从不相信输入。对不起,大声喊叫。还要尝试为变量使用更有意义的名称-Intellisense在任何情况下都可以节省大量键入,所以为什么不利用这些帮助来创建更容易理解的程序。空行s也能帮上忙。祝你好运。我在@HenkHolterman指出它之后就修复了覆盖。我知道我的代码有点乱,变量看起来完全出乎意料,我的时间有点短,所以它们只是首字母缩写(tI=文本迭代器,tL=文本长度),但我想问些别的问题,这一直困扰着我(双关语不是故意的),如果断点位于
    string match=”“
    之前的任何一行,您知道为什么我的调试不继续进行吗?但是错误会被抛出,如果没有匹配,而不是之前,它不应该被抛出在
    char*c=new char[match.length()-1];
    const char* KMP(const char* text, const char* str)
    {
        int tL = strlen(text);
        int sL = strlen(str);
        string match = "";
    
        if (sL == 0 || tL == 0)
            throw "both text and string must be larger than 0";
        else if (sL > tL)
            throw "the text must be longer than the string";
    
        int tI = 0;
        int col = 0, row = 0;
    
        while (tI <= tL - sL)
        {
            int i = 0;
            int tmpCol = -1;
            int next = 1;
            for (; i <= sL && text[i + tI] != '\0'; i++)
            {
                if (text[i + tI] == '\n')
                {
                    row++;
                    tmpCol++;
                }
                if (text[i + tI] == str[0] && next == 1 && i > 0)
                    next = i;
    
                if (text[i + tI] != str[i])
                    break;
            }
            if (i == sL)
            {
                match += to_string(row) + ',' + to_string(col) + ';';
            }
    
            tI += next;
    
            col = tmpCol > -1 ? tmpCol : col + next;
        }
        char* c = new char[match.length() - 1];
        c[match.length() - 1] = '\0';
        for (int i = 0; i < match.length() - 1; i++)
            c[i] = match[i];
        return c;
    }
    
    ...
    if (match.length() == 0)
        return "No matches";
    
    // Allocate for all chars + \0 except the last semicolon
    char* c = new char[match.length()];
    c[match.length() - 1] = '\0';
    
    // Copy all chars except the last semicolon
    for (int i = 0; i < match.length() - 1; i++)
        c[i] = match[i];
    
    return c;