【问题标题】:(lib)mpg123 use of function mpg123_index in C#(lib)mpg123 在 C# 中函数 mpg123_index 的使用
【发布时间】:2018-03-05 07:51:53
【问题描述】:

我在我的项目中使用 mpg123 来解码 mp3。我与开发人员(Thomas Orgis)讨论了搜索时的性能问题,他有一个好主意:扫描文件,然后将扫描的索引设置为播放句柄。 所以我想在我的 C# 项目中使用 mpg123_index 和 mpg123_set_index 并使用 libmpg123 的包装器。

包装器不是自己写的,我也联系了开发者,但他似乎无法使用。所以可能有人有指针编程的知识,我自己也做过一些事情,但目前我在调用方法时只得到一个AccessViolationException。

这里有一些代码: 包装规范(也许这是错误的?!):

[DllImport(Mpg123Dll)]public static extern int mpg123_index(IntPtr mh, IntPtr offsets, IntPtr step, IntPtr fill);

网站规格(C):

https://www.mpg123.de/api/group__mpg123__seek.shtml#gae1d174ac632ec72df7dead94c04865fb

MPG123_EXPORT int mpg123_index ( mpg123_handle * mh, off_t ** 偏移量,off_t * 步长,size_t * 填充)

授予对为查找而管理的帧索引表的访问权限。你 被要求不要修改值...使用 mpg123_set_index 设置 寻找索引

参数 mh手柄 偏移指向索引数组的指针 第一步索引字节偏移量推进了这么多 MPEG 帧 填充记录的索引偏移量;数组大小

返回 MPG123_OK 成功

我尝试在 C# 中使用该函数:

IntPtr pIndex = IntPtr.Zero;
IntPtr pFill = IntPtr.Zero;
IntPtr pStep = IntPtr.Zero;
if (MPGImport.mpg123_index(this.mp3Handle,pIndex,pStep,pFill) != (int)MPGImport.mpg123_errors.MPG123_OK)) 
{
    log.error("Failed!");
}

那么,有人知道如何在 C# 端正确使用该函数吗?我刚刚从 mpg123 的作者那里得到信息,pIndex 将是指向内部索引的指针。所以这个指针会被这个函数改变。

感谢您的帮助。

真诚的 斯文

编辑: 现在下面的代码几乎可以工作了:

[DllImport(Mpg123Dll)]public unsafe static extern int mpg123_index(IntPtr mh, long **offsets, long *step, ulong *fill);
[DllImport(Mpg123Dll)]public unsafe static extern int mpg123_set_index(IntPtr mh, long* offsets, long step, ulong fill);

public static Boolean CopyIndex(IntPtr _sourceHandle,IntPtr _destinationHandle)
{
    Boolean copiedIndex = false;
    unsafe
    {
        long* offsets = null; 
        long step = 0;
        ulong fill = 0;
        int result = MPGImport.mpg123_index(_sourceHandle, &offsets, &step, &fill);
        if (result == (int)MPGImport.mpg123_errors.MPG123_OK)
        {
            result = MPGImport.mpg123_set_index(_destinationHandle, offsets, step, fill);
            if (result == (int)mpg123_errors.MPG123_OK)
            {
                copiedIndex = true;
            }
        }
    }
    return copiedIndex;
}

result = MPGImport.mpg123_set_index(_destinationHandle, offsets, step, fill); 上,结果为-1,即MPG123_ERR = -1, /**< Generic Error */

【问题讨论】:

  • public static extern int mpg123_index(IntPtr mh, IntPtr offsets, IntPtr step, IntPtr fill); 不行,函数MPG123_EXPORT int mpg123_index ( mpg123_handle * mh, off_t ** offsets, off_t * step, size_t * fill ) 的参数中指向 int 的指针为零,这显然是错误的
  • 感谢您的评论 :)。我已经假设签名中有错误。你知道它应该是什么样子吗?
  • 我真的不知道,但我会尝试使用 public static extern int mpg123_index(IntPtr mh, long **offsets, long *step, ulong *fill); 这样的电话 long *offsets = null; long step = ???; ulong fill= ???; iMPGImport.mpg123_index(this.mp3Handle, &offsets, &step, &fill);
  • 谢谢,这似乎可行,我得到了回复。我编辑了这个问题。现在唯一的问题是将索引存储回目标句柄。你有什么想法,为什么这会失败?

标签: c# c pointers mono


【解决方案1】:

工作代码:

[DllImport(Mpg123Dll)]public unsafe static extern int mpg123_index(IntPtr mh, long **offsets, long *step, ulong *fill);
[DllImport(Mpg123Dll)]public unsafe static extern int mpg123_set_index(IntPtr mh, long* offsets, long step, ulong fill);

public static Boolean CopyIndex(IntPtr _sourceHandle,IntPtr _destinationHandle)
{
    Boolean copiedIndex = false;
    unsafe
    {
        long* offsets = null; 
        long step = 0;
        ulong fill = 0;
        int result = MPGImport.mpg123_index(_sourceHandle, &offsets, &step, &fill);
        if (result == (int)MPGImport.mpg123_errors.MPG123_OK)
        {
            result = MPGImport.mpg123_set_index(_destinationHandle, offsets, step, fill);
            if (result == (int)mpg123_errors.MPG123_OK)
            {
                copiedIndex = true;
            }
        }
    }
    return copiedIndex;
}

_sourceHandle 和 _destinationHandle 可能不是 IntPtr.Zero,那是我的错误。感谢 Stargateur,非常好的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    • 2015-06-20
    • 1970-01-01
    相关资源
    最近更新 更多