在 libnfc 上使用 pinvoke 获取字符串值的无效指针异常

问题描述

我正在尝试使用 dotnet core 与 raspBerry pi 3 上的 NFC 读写器进行通信。

我不得不说我使用的不同的 libnfc 命令行工具都运行良好(也就是我可以读取和轮询我的标签,这方面没问题)。

这个想法是使用 dotnet core 和 C# 来编排 libnfc 库,它似乎工作正常,除非我调用函数返回一个字符串,我收到以下错误消息:

*** Error in `./NfcTest': free(): invalid pointer: 0x6d4ebc00 ***

NfcTest 当然是我的应用程序的名称

这里是 pinvoke 定义

[DllImport("libnfc",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string nfc_version();

请注意,在网上查找后,我确实自己添加[return] 属性,但它没有对结果做出任何改变。引发了同样的错误

libnfc 中 nfc_version 的代码在这里https://github.com/nfc-tools/libnfc/blob/c3f739dea339a71c59d7d53ab6b0ecc477c3ab73/libnfc/nfc.c#L1325

它似乎返回了一个“常量”,并且没有进行任何形式的释放。所以我的猜测是我错误地配置了其中一个属性

一个例子是我调用以下内容

[DllImport("libnfc",CallingConvention = CallingConvention.Cdecl)]
public static extern string nfc_device_get_name(IntPtr pnd);

虽然我可以使用指针(pnd param)完美地调用其他方法(即轮询),但调用方法返回与 Version 方法相同的错误。返回字符串的两种方法都让我想知道问题是否不在 DllImport 中,但我不太确定如何解决

链接到该示例的库代码https://github.com/nfc-tools/libnfc/blob/c3f739dea339a71c59d7d53ab6b0ecc477c3ab73/libnfc/nfc.c#L1215

任何智慧将不胜感激。

解决方法

来自 Matthew Watson 和 link he shared 的评论给出了正确答案!

所以我像这样修改了 pinvoke 行:

[DllImport("libnfc",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr nfc_version();

然后我这样称呼它:

public string Version()
{
    IntPtr ptr = Functions.nfc_version();
    var str = Marshal.PtrToStringAuto(ptr);
    return str;   
}

它就像一个魅力!

谢谢!

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...