C#<-&燃气轮机;C++;DLLImport";试图读取或写入受保护内存。”; 我有一个C++ DLL,它在其中有一个函数,我试图从C语言应用程序调用。 这里是C++头文件中的代码 extern "C" _declspec(dllexport) int LabelStoringSSDsim(int devNum, UCHAR serial[40], UCHAR wwn[40], UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode); 这里是C++源文件中的代码 int LabelStoringSSDsim(int devNum, UCHAR serialLbl[40], UCHAR wwnLbl[40], UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode) { string strConfigID="12111"; //5 bytes string strFrmRev="1.25...."; //8 bytes string strDevName="ABC-123................................."; //40 bytes for (int i=0;i<5;i++) ConfigID[i] = strConfigID[i]; for (int i=0;i<8;i++) FrmRev[i] = strFrmRev[i]; for (int i=0;i<40;i++) DevName[i] = strDevName[i]; return eCode; }
因此,当我到达代码的最后一位时,我得到了“试图读取或写入受保护的内存。这通常表示其他内存已损坏。”错误 我以前没有这样导入DLL的经验,我做了很多搜索,但似乎找不到解决问题的方法 我试着用一个返回整数的简单函数从头开始,结果成功了。然后我添加了一个int来传递给函数,它仍然有效。然后我添加了一个字节数组供我传递,这很有效。然后我尝试将该字节数组转换为引用,但失败了。我猜我的数据回错了C#<-&燃气轮机;C++;DLLImport";试图读取或写入受保护内存。”; 我有一个C++ DLL,它在其中有一个函数,我试图从C语言应用程序调用。 这里是C++头文件中的代码 extern "C" _declspec(dllexport) int LabelStoringSSDsim(int devNum, UCHAR serial[40], UCHAR wwn[40], UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode); 这里是C++源文件中的代码 int LabelStoringSSDsim(int devNum, UCHAR serialLbl[40], UCHAR wwnLbl[40], UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode) { string strConfigID="12111"; //5 bytes string strFrmRev="1.25...."; //8 bytes string strDevName="ABC-123................................."; //40 bytes for (int i=0;i<5;i++) ConfigID[i] = strConfigID[i]; for (int i=0;i<8;i++) FrmRev[i] = strFrmRev[i]; for (int i=0;i<40;i++) DevName[i] = strDevName[i]; return eCode; },c#,c++,reference,dllimport,C#,C++,Reference,Dllimport,因此,当我到达代码的最后一位时,我得到了“试图读取或写入受保护的内存。这通常表示其他内存已损坏。”错误 我以前没有这样导入DLL的经验,我做了很多搜索,但似乎找不到解决问题的方法 我试着用一个返回整数的简单函数从头开始,结果成功了。然后我添加了一个int来传递给函数,它仍然有效。然后我添加了一个字节数组供我传递,这很有效。然后我尝试将该字节数组转换为引用,但失败了。我猜我的数据回错了 非常感谢您的帮助。尝试将[In]更改为[In,Out]。我也不确定是否在单个参数上同时使用ref和[In,Out
非常感谢您的帮助。尝试将
[In]
更改为[In,Out]
。我也不确定是否在单个参数上同时使用ref
和[In,Out]
关键字。(编辑:汉斯·帕桑在下面的评论中很好地解释了两者之间的差异。)
有关更多信息,请参阅,特别是文章“出于性能原因,默认情况下,按值传递的引用类型(类、数组、字符串和接口)被封送为In参数。除非将InAttribute和OutAttribute(或仅OutAttribute)应用于方法参数,否则不会看到这些类型的更改。”升级到Windows 7后,我开始定期在本机互操作过程中遇到此异常。代码一直在XP上运行,如果我在XP兼容模式下运行我的应用程序,那么Win7上的问题就更少了 经过一些研究和实验后,我发现我出现这种异常的原因与调用返回字符串的本机函数(WCHAR*)有关 我认为目前还没有解决这个问题的方法,因为即使更新到.NET3.5也没有解决这个问题… 然而,我确实发现了以下工作 适用于XP但不适用于Win 7的示例:
[DllImport("NativeBin.dll")]
public static extern String GetWCharStr();
在Win 7和XP上对我有效的示例:
[DllImport("NativeBin.dll")]
private static extern IntPtr GetWCharStr();
public static String GetString()
{
return Marshal.PtrToStringUni(GetWCharStr());
}
这会产生以下错误:抛出了“System.ExecutionEngineeException”类型的异常。@Chris,我想我有语法错误。请尝试上面我的新改进版本。抱歉,仍然是一样的:X--错误发生在代码的最后一位,而不是以前的错误。您在添加[in,Out]时删除ref的提示使我成功了。非常感谢你。由于缺乏声誉,我似乎无法回答你的问题。我很感激你。是的,就是这样。ref或out说明符(通过引用传递)使其成为指向指针的指针,因为数组已经是引用类型。[In]和[Out]在其他方面没有效果,它们只是告诉封送拆收器何时需要复制指向的值。[In,Out]是默认值,如果您不关心非托管代码所做的任何修改,请忽略[Out]。这是一个优化。
[DllImport("NativeBin.dll")]
private static extern IntPtr GetWCharStr();
public static String GetString()
{
return Marshal.PtrToStringUni(GetWCharStr());
}