C# 从dll调用函数时分配大小无效
我刚开始使用dll,但我以前没有遇到过这个问题,所以它可能没有dll连接。我有C++中实现的KMP字符串匹配算法,我用DLL调用它。p> 这是我的出口: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
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.:我还发现您的代码有一些问题:
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;