通过互操作接收字符串

2023-12-09

我无法从我编写的一些 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 参数中。但是我想要那个长变量!我做错了什么或令人不安,以便通过在那里使用那么长的参数来强制崩溃?


然而我想要那个长变量

那么你应该在 C 中将参数定义为long long。正如 Lucero 指出的,C++ 中的 long 是 32 位,而 C# 中的 long 是 64 位。因此,如果您传递 64 位值,而 C 函数需要 32 位值,则该函数会读取额外的 32 位作为第二个参数,这显然会导致缓冲区地址错误......

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过互操作接收字符串 的相关文章

随机推荐

  • SQL Server:并发线程可以更新同一行吗?

    我有一个具有此 UPDATE 查询的存储过程 UPDATE TOP 1 Batch tbl SET locked 1 OUTPUT inserted batchId INTO batchId FROM Batch tbl WHERE loc
  • ASP.NET MVC 中的所有内置 ActionResults

    我正在寻找 ASP NET MVC 控制器中可用的内置 第 3 方将是一个额外的 ActionResults 列表 到目前为止 我发现了以下内容 ContentResult this Content ActionResult this Vi
  • 301 重定向与 DNS 更改:终止 301 重定向并更新子域的 DNS 是否安全?

    我有一个在子域上运行的站点 该子域已迁移到新服务器和新域名 为了保留搜索积分 我知道 301 重定向是处理迁移转换的正确方法 营销部门提到的 301 重定向是我从未听说过的 从技术角度来看 我不明白你必须维持重定向多长时间 有人可以解释一下
  • C++静态库中的共享全局变量:Linux

    在 C 中 静态库 A 定义了一个全局变量 foo B 和 C 是两个动态库 都依赖于 A 因此与 A 链接 静态 然后B和C最终加载在同一个进程中 例如 应用程序负载 B 和 C 如果我们在 Windows 环境中 我们将获得 foo 的
  • 如何检查访问者的IP地址是否仍然有效或在线?

    是否可以使用 IP 地址检查访问者是否仍然在线 我已经创建了一个 javascript 和 php 来检查访问者的 IP 地址 当他们使用 onLoad 和 onBeforeUnload 事件打开我的页面之一时 但在某些情况下 我的脚本无法
  • PHP 返回循环结果

    我对编码和 PHP 世界都是新手 想知道如何使用return循环时 例如我想返回 显示 1 10 但不使用 echo start 1 end 11 for start start lt end start start 1 echo star
  • 在 C 中将字节转换为 Int / uint

    我有一个无符号字符数组 248 充满字节 如 2F AF FF 00 EB AB CD EF 这个数组是我的字节流 我将来自 UART RS232 的数据存储为缓冲区 现在我想将字节转换回 uint16 和 int32 在 C 中 我使用
  • 按 Home 键后运行的 Android 服务

    我有一个 Android 服务 是使用 StartService 在应用程序的第一个 Activity 的 OnCreate 中创建的 我需要此服务在应用程序的整个生命周期中运行 即应用程序中的所有活动 但在用户按下主页键或后退按钮后 服务
  • Android java.net.SocketTimeoutException:连接超时

    最近我的程序中遇到了以下错误 11 18 12 30 30 259 W System err 21368 java net SocketTimeoutException Connection timed out 11 18 12 30 30
  • Typescript Mongoose 以类型安全的方式忽略查询结果中的某些字段

    我正在使用 Nestjs 和 Mongoose 我需要获取用户配置文件 但忽略 Mongodb 中的密码 我的用户架构如下所示 Schema export class User extends Document Prop required
  • 如何将字节数组数据放入DoubleBuffer

    我想从字节数组中提取一组坐标到 DoubleBuffer 中 下面是如何将一组坐标从主字节数组提取到另一个字节数组的示例 byte intPoints new byte 4 byte geomCoords is new ByteArrayI
  • .net WebService,绕过 ssl 验证!

    好吧 我正在使用一个 Web 服务 该服务的证书未 100 正确设置 该证书是为域 domain1 com 设置的 并且 api 位于soap shop domain1 com SOAP 现在我无法连接到此webservice 然后我得到一
  • GetModuleHandle(),用于另一个进程中的 DLL

    标题确实解释了这一切 我有一个进程利用另一个进程 我需要能够在该程序上获取某个非 Windows 标准的 DLL 并且我没有主程序的源代码 我需要使用它通过 GetProcAddress 调用导出函数 并最终在 CreateRemoteTh
  • 比较Java中不同类的对象字段

    我有两个对象 每个对象都有数十个字段 Class1 int firstProperty String secondProperty Class2 int propertyOne String propertyTwo 虽然有些字段的名称不同
  • 使 WooCommerce 中不需要结账地址字段

    在 Woocommerce 中 我试图使用下面的代码使结账地址字段不需要 但我有这个错误提交结帐表格时 请输入地址以继续 我设置不需要的地址结帐字段的代码 add filter woocommerce billing fields wc n
  • JSON 到 PHP 关联数组

    你们中有人知道将其放入关联数组的好方法吗 我努力了json decode但发现并没有太大帮助 这是我需要放入关联数组的数据 data name Joe Bloggs id 203403465 name Fred Bloggs id 2547
  • IBM Worklight - 在哪里可以找到以前的版本

    我希望使用 IBM Worklight v5 0 5 Fix pack 1 设置 Eclipse 开发环境 我可以获得有关旧版本 Worklight 的安装链接的一些指示吗 请参阅下面的可用下载 请注意 这些链接并不能保证每次下载都是每个版
  • KeyHolder插入db2表后获取主键值

    再会 我在 db2 中有一个表 其中主表is autoincrement被设定为Yes 意味着每次向该表插入数据时 不需要传入主键值 因为它会自动生成 但是 我需要在插入后取回主键值 代码如下 public integer insertRe
  • PHP Traits:如何解决属性名称冲突?

    当类使用两个 Traits 时如何解决属性名称冲突同名属性 Example
  • 通过互操作接收字符串

    我无法从我编写的一些 C 代码中获取字符串 首先是一些通常不相关的背景信息 我想从 TAPI API 接收 TAPI TSP 的用户可读字符串 我已经实现了一个半可行的 TAPI 解决方案 依赖于将驱动程序名称与存储的字符串相匹配 但希望将