【问题标题】:F# Pinvoke errorF# Pinvoke 错误
【发布时间】:2014-01-28 17:14:05
【问题描述】:

我几天前发布了这个,但我得到的答案似乎不起作用,所以我再次发布它并提供更多细节。

我有一个用 F# 编写的项目,我必须为其中的一部分使用非托管 DLL。在非托管 DLL 的文档中,他们提供了如何从 C# 调用函数的示例,如下所示:

using System;
using System.Runtime.InteropServices;

[DllImport("foo.dll")] public static extern Int32 foo_init(
    [MarshalAs(UnmanagedType.AnsiBStr), In()] ref string FOOarg_Handle,
    [MarshalAs(UnmanagedType.AnsiBStr), In()] ref string FOOarg_User, 
    [MarshalAs(UnmanagedType.AnsiBStr), Out()] out string FOOarg_DataOut, 
    [MarshalAs(UnmanagedType.AnsiBStr), Out()] out string FOOarg_ErrOut);

我尝试将其翻译成 F#,并尝试了以下操作:

open System
open System.Runtime.InteropServices

[<DllImport(@"foo.dll", EntryPoint="foo_init")>]
extern int fooInit([<MarshalAs(UnmanagedType.AnsiBStr)>]string handle,
                   [<MarshalAs(UnmanagedType.AnsiBStr)>]string user,
                   [<MarshalAs(UnmanagedType.AnsiBStr)>]string result,
                   [<MarshalAs(UnmanagedType.AnsiBStr)>]string error)

然后我尝试调用该函数:

let res = fooInit("", "", "", "")

很遗憾,这不起作用。它可以编译,但是当我运行它时,我最终会遇到 Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 错误。

有人知道如何解决这个问题吗?提前致谢!

【问题讨论】:

  • 您需要将指针传递给字符串。这就是refout 所暗示的。

标签: .net winapi f# pinvoke extern


【解决方案1】:

实际上,这似乎有效:

open System
open System.Runtime.InteropServices

[<DllImport(@"foo.dll", EntryPoint="foo_init")>]
extern int fooInit([<MarshalAs(UnmanagedType.AnsiBStr)>]string& handle,
                   [<MarshalAs(UnmanagedType.AnsiBStr)>]string& user,
                   [<MarshalAs(UnmanagedType.AnsiBStr)>]string& result,
                   [<MarshalAs(UnmanagedType.AnsiBStr)>]string& error)

然后我必须这样调用函数:

let mutable h, u, r, e = "", "", "", ""

let res = fooInit(&h, &u, &r, &e)

这篇文章帮助我弄清楚了:http://pblasucci.wordpress.com/2012/07/23/managing-pointers-or-fs-platform-invoke-gotcha/

【讨论】:

    【解决方案2】:

    您需要复制 [In][Out] 值以及 MarshalAs 值。

    【讨论】:

    • 不幸的是,这不起作用。我尝试像这样添加[&lt;In&gt;][&lt;Out&gt;] 装饰器:[&lt;MarshalAs(UnmanagedType.AnsiBStr)&gt;][&lt;In&gt;]string handle。遇到了同样的异常。
    猜你喜欢
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    相关资源
    最近更新 更多