如何在C#中从第三方C++库提取数据到结构体指针?
解决CS0165错误:未赋值指针调用第三方API的方案
你遇到的CS0165错误核心原因是:data指针只做了声明,没有分配任何有效内存,属于未初始化的野指针,C#编译器会阻止这种危险操作。结合你的场景,这里提供两种直接可行的解决办法,都不需要修改第三方API:
方法1:用stackalloc分配栈内存
stackalloc可以在栈上直接分配指定大小的内存,刚好适配DataStruct的需求,内存会在方法执行完毕后自动释放,无需手动管理。
代码示例
unsafe { // 分配能容纳1个DataStruct的栈内存,直接得到对应指针 DataStruct* data = stackalloc DataStruct[1]; var error = Wrapper.GetData(data); // 读取API写入的数据 DataStruct result = *data; // 后续使用result即可 }
也可以按字节数分配内存再强制转换,效果完全一致:
unsafe { byte* buffer = stackalloc byte[sizeof(DataStruct)]; DataStruct* data = (DataStruct*)buffer; var error = Wrapper.GetData(data); }
方法2:用fixed关键字固定栈上结构体地址
先声明一个栈上的DataStruct实例,通过fixed关键字获取它的内存地址,API会直接把数据写入这个实例中,操作更直观。
代码示例
unsafe { // 初始化一个栈上的结构体实例 DataStruct dataInstance = new DataStruct(); // 固定实例的内存地址,防止被移动(栈上实例本来不会被GC移动,但fixed能合法获取指针) fixed (DataStruct* data = &dataInstance) { var error = Wrapper.GetData(data); } // 此时dataInstance已经被API写入数据,直接使用即可 Console.WriteLine(dataInstance.SomeMember); }
注意事项
- 确保你的项目已经开启允许不安全代码:在项目属性的「生成」选项卡中勾选对应选项
- 两种方法都是栈内存分配,不会产生GC压力,对于120字节的
DataStruct来说完全高效安全 - 不要用堆分配(比如
new DataStruct())来获取指针,堆上对象可能被GC移动,除非必须用fixed固定,但栈分配更适合这种场景
内容的提问来源于stack exchange,提问作者TJR
相关产品推荐
相关产品推荐

