【问题标题】:Freetype .net wrapper problems (attempted to write protected memory exception)Freetype .net 包装器问题(试图写入受保护的内存异常)
【发布时间】:2012-04-06 10:33:13
【问题描述】:

我正在尝试为 .net 设置 freetype2,但我仍然不够幸运。所以我使用来自this question 的答案。目前,我尝试使用 Init_FreeType 函数时遇到一个异常,我试图将其写入受保护的内存。我使用的代码如下:

Intptr library = new Intptr();
FreeType.FT.Init_FreeType(library);

包装器中Init_FreeType函数的声明如下:

[DllImport(FT_DLL, EntryPoint = "FT_Init_FreeType"), SuppressUnmanagedCodeSecurity]
public static extern int Init_FreeType(IntPtr /*IntPtr LibraryRec_*/ alibrary);

有什么想法吗?

【问题讨论】:

    标签: .net freetype2


    【解决方案1】:

    在我看来 Init_FreeType 的声明是错误的。应该是:

    public static extern int Init_FreeType(ref IntPtr alibrary);
    

    (参数是ref)。并称之为:

    IntPtr library = IntPtr.Zero;
    FreeType.FT.Init_FreeType(ref library);
    

    我怀疑发生了什么是Init_FreeType 将传递的值视为引用并尝试将库句柄存储在该内存位置。但是,由于您传递的是指针的 (而不是指针位置),因此它会陷入困境。

    回应评论的更多信息:

    FT_Init_FreeType 的文档将其定义为:

    FT_EXPORT( FT_Error ) FT_Init_FreeType( FT_Library  *alibrary );
    

    FT_ErrorintFT_Library

    typedef struct FT_LibraryRec_  *FT_Library;
    

    所以您在通话中肯定需要ref。托管原型应该如我上面所示。

    堆栈不平衡几乎肯定是由错误的调用约定引起的。在 .NET 中,默认调用约定是 stdcall。在我看来,FreeType 正在使用 cdecl 调用约定。所以你的DllImport 应该是:

    [DllImport(FT_DLL, EntryPoint="FT_Init_FreeType", 
        CallingConvention=CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
    

    【讨论】:

    • 好吧,我刚试过,但我怀疑这是问题所在。在 Init_FreeType 上运行代码时收到以下消息:“检测到 PInvokeStackImbalance。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配”
    • 确实,我按照您更新的答案更改了我的代码,现在它可以工作了。现在我必须根据您的建议更改包装器中的几乎每个函数,因为其他函数也会抛出相同的异常。谢谢:)
    猜你喜欢
    • 2013-08-05
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    • 2011-09-16
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 2019-12-19
    相关资源
    最近更新 更多