我在C(使用Code :: Blocks)中构建了一个在.NET程序中导入的dll(使用Visual Studio 2010)。 一个函数(在dll中)将一个字符串返回给主程序,该字符串在Texbox中显示该字符串,但我唯一看到的是一组混乱的字符或根本没有。
我试图解决它,但我只发现问题是如何构建字符串,例如 如果我直接写
return "This is a string.";
或
char* temp = "This is a string.";
return temp;
它完美无缺,但如果我使用
之类的东西char temp[30];
strcpy(temp, "This is ");
strcat(temp, "a string.");
return temp;
或
char temp[30];
temp[0] = 'T';
temp[1] = 'e';
temp[2] = 's';
temp[3] = 't';
temp[4] = '\0';
return temp;
或
char* temp;
temp = (char*)malloc(sizeof(char)*10);
strcpy(temp, "Test");
return temp;
在前两种情况下,程序显示混乱的字符,而在最后一种情况下,它会崩溃。
---------- [更新] ----------
你是对的,这是一个愚蠢的错误! :O这是我第一次尝试将C DLL用于.NET库,因此我可以将代码放在这里(这只是一个测试,所以代码il真的很短)
我是如何宣布这个功能的
Declare Function Serial Lib "Test.dll" Alias "_Z9getSerialv" () As String
我称之为
TextBox1.Text = Serial()
这就是DLL的代码
#include "main.h"
char* DLL_EXPORT getSerial()
{
int n1 = 987, n2 = 123, n3 = 563;
char num1[30], num2[30], num3[30];
char *final1 = (char*)calloc(90, sizeof(char));
itoa(n1,num1,10);
itoa(n2,num2,10);
itoa(n3,num3,10);
strcpy(final1, num1);
strcat(final1, "/");
strcat(final1, num2);
strcat(final1, "/");
strcat(final1, num3);
return final1;
}
我尝试在Code :: Blocks中调试DLL,将我在VS2010中构建的程序附加到它(进入Code :: Blocks to Project - > gt; Set Program' s Argument - > Host Application),但它并没有停在断点处。试图调试主程序,VS2010弹出一个MsgBox,上面写着:试图读取或写入受保护的内存。这通常表明其他内存已损坏。
调试Codeblocks中的DLL,该应用程序显示预期的结果......但如果我正常运行该应用程序,它会崩溃(使用相同的dll,相同的应用程序,在同一目录中)。我认为这与code :: blocks(可能)共享dll和主机应用程序之间的内存有关,或者更多可能与解除分配的内存有关,但我仍然不知道如何解决它。
答案 0 :(得分:1)
在前两种情况下,您将返回局部变量temp
的地址。一旦函数返回,temp
就不再存在,这意味着它保存的字符串(存储在堆栈中)不再有效,并且可能被不同的函数调用覆盖。
就最后一种情况而言,看起来就像它应该工作一样 - 我唯一能想到的是C运行时没有被正确初始化,而malloc
是导致未定义的行为。
答案 1 :(得分:0)
OP解决方案。
我解决了仅编辑.NET程序的问题:
Declare Function Serial Lib "Test.dll" Alias "_Z9getSerialv" () As IntPtr
TextBox1.Text = Marshal.PtrToStringAnsi(Serial())