我无法从我编写的一些 C 代码中获取字符串。
首先是一些通常不相关的背景信息:我想从 TAPI API 接收 TAPI TSP 的用户可读字符串。我已经实现了一个半可行的 TAPI 解决方案,依赖于将驱动程序名称与存储的字符串相匹配,但希望将其更改为在永久线路 ID 上工作,因为我们的一个客户拥有一个 (阿尔卡特) PBX,它拒绝以任何其他方式工作。
在 C 中,我在头文件中将函数定义为:
__declspec(dllexport) void GetDeviceName(long DeviceId, wchar_t* DeviceName);
函数是这样写的:
__declspec(dllexport) void GetDeviceName(long DeviceId, wchar_t* DeviceName)
{
//tapi code here...
//copy the string to DeviceName
wcscpy(DeviceName, (wchar_t*)((char *)devCaps + devCaps->dwLineNameOffset));
}
如上所述,这最终会做一些有用的事情,但现在如果 abc 被放置在我的 wchar_t*/StringBuilder 中并且我可以在 C# 中看到它,我会很高兴。
在 C# 中,我将函数定义为:
[DllImport("SBW.Tapi.TapiInterop.dll", CharSet = CharSet.Auto)]
static extern void GetDeviceName(long DeviceId, StringBuilder DeviceName);
我将设备名称定义为 StringBuilder,因为字符串是不可变的,并且我希望在 C 中设置设备名称(这是MS推荐的)。我还将返回类型设置为void
希望这也会影响某些事情(参见this半有用的单一文章,用于部分伪科学解释)。
并这样称呼它:
StringBuilder name = new StringBuilder();
name.EnsureCapacity(100);
long n = 0;
GetDeviceName(n, name);
我将调试器附加到正在运行的进程,设置一个断点,并注意到 C 代码中 StringBuilder 不知何故被扭曲并作为空指针提供给非托管代码。
随后在 C# 中抛出 AccessViolationException。
出了什么问题?
删除长参数会有所帮助。我可以将“abc”添加到 C 中的 DeviceName 参数中。但是我想要那个长变量!我做错了什么或令人不安,以便通过在那里使用那么长的参数来强制崩溃?