C# P/Invoke 尝试使用字符串参数时出现 AccessViolationException
C# P/Invoke AccessViolationException when attepting to use string parameters
我正在尝试包装一个只有头文件的 C++ dll。我现在尝试使用的功能是 AccessViolationException
:
"Attempted to read or write protected memory.
This is often an indication that other memory is corrupt."
C++函数原型为:
RunSimulation( LPCSTR, LPSTR);
同时,我的 C# 包装器是:
[DllImport("thedll.dll", EntryPoint = "RunSimulation")]
public static extern uint RunSimulation(string simID, ref string outputID);
我怀疑问题出在 C# 函数上,特别是字符串的实现方式。由于我对平台调用等比较陌生,所以我不确定如何进行。
字符串参数应该是指向字符串所在位置的指针吗?还是包装纸有其他问题?
编辑:
这是在事物的托管端调用函数的方式:
string outputID = "";
try
{
RunSimulation(id, ref outputID);
}
catch (Exception e)
{
Logging.Log_Warning.SendException("Threw an exception", e);
}
编辑 2:
将第二个参数更改为 StringBuilder
后,会发生相同的异常。唯一的区别是异常中断不会在调用函数的行停止,Visual Studio 打开一个新的 "Break" 选项卡,说明异常发生了。函数文档建议预留16字节以上,所以我使用了取值为1024和4096的capacity构造函数来测试。
编辑 3:
进行清理和重建后,问题表现为驱动程序错误。由于这表明 API 正在运行,因此解决方案确实是按照评论中的建议将我的 ref string
参数更改为 StringBuilder
。
我的问题的解决方案最终是使用 StringBuilder 而不是 String 来确保提前分配内存中的 space。所以我的签名最终看起来像:
[DllImport("thedll.dll", EntryPoint = "RunSimulation")]
public static extern uint RunSimulation(string simID, StringBuilder outputID);
并使用它:
string id = "someID";
int requiredSize = 512;
StringBuilder outputID = new StringBuilder(requiredSize);
RunSimulation(id, outputID);
希望对您有所帮助!
我正在尝试包装一个只有头文件的 C++ dll。我现在尝试使用的功能是 AccessViolationException
:
"Attempted to read or write protected memory.
This is often an indication that other memory is corrupt."
C++函数原型为:
RunSimulation( LPCSTR, LPSTR);
同时,我的 C# 包装器是:
[DllImport("thedll.dll", EntryPoint = "RunSimulation")]
public static extern uint RunSimulation(string simID, ref string outputID);
我怀疑问题出在 C# 函数上,特别是字符串的实现方式。由于我对平台调用等比较陌生,所以我不确定如何进行。
字符串参数应该是指向字符串所在位置的指针吗?还是包装纸有其他问题?
编辑:
这是在事物的托管端调用函数的方式:
string outputID = "";
try
{
RunSimulation(id, ref outputID);
}
catch (Exception e)
{
Logging.Log_Warning.SendException("Threw an exception", e);
}
编辑 2:
将第二个参数更改为 StringBuilder
后,会发生相同的异常。唯一的区别是异常中断不会在调用函数的行停止,Visual Studio 打开一个新的 "Break" 选项卡,说明异常发生了。函数文档建议预留16字节以上,所以我使用了取值为1024和4096的capacity构造函数来测试。
编辑 3:
进行清理和重建后,问题表现为驱动程序错误。由于这表明 API 正在运行,因此解决方案确实是按照评论中的建议将我的 ref string
参数更改为 StringBuilder
。
我的问题的解决方案最终是使用 StringBuilder 而不是 String 来确保提前分配内存中的 space。所以我的签名最终看起来像:
[DllImport("thedll.dll", EntryPoint = "RunSimulation")]
public static extern uint RunSimulation(string simID, StringBuilder outputID);
并使用它:
string id = "someID";
int requiredSize = 512;
StringBuilder outputID = new StringBuilder(requiredSize);
RunSimulation(id, outputID);
希望对您有所帮助!