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);

希望对您有所帮助!