pInvoke、.net 4 与 3.5

发布于 2024-10-07 19:20:00 字数 2588 浏览 9 评论 0原文

我有一个关于从托管代码到非托管代码的 p/invoke 的问题。请参阅我在 MSDN 论坛上的原始帖子< /a> (如本文后面的简要总结所示)。在继续之前,我只想解释几件事:我在 net 3.5 中有一个包装器程序集,它对非托管代码进行实际的互操作。然后我有我的控制台“主机应用程序”,它使用包装程序集。

我提出的解决方案(我参考我的 MSDN 帖子)在主机应用程序使用 .net 4 时有效,但在将主机应用程序更改为使用 .net 3.5 时不起作用。更改时,我收到 AccessViolationException。

  • 主机应用程序:4.0,包装程序集:3.5 ->作品
  • 主机应用程序:3.5,包装程序集:3.5 ->投掷 AccessViolationException

有人知道我为什么会收到 AccessViolationException 吗?最重要的是,如何让它与 .net 3.5 一起工作?

我参考的 MSDN 帖子的简要摘要。我有这个混乱的 p/Invoke 我需要解决。 C 声明如下所示:

long TBAPI TbeAndring (short, 
            short,
            PTB_PU,
            PTB_ANDRING_INFO,
            PTB_PARAMS,
            PTB_PREMIE_NIVA_INFO,
            PTB_PREMIE,
            PTB_FORMAN_INFO,
            PTB_FORMAN,
            PTB_FUNK,
            PTB_PARAMS,
            PTB_PREMIE_NIVA_INFO,
            PTB_PREMIE,
            PTB_FORMAN_INFO,
            PTB_FORMAN,
            PTB_FUNK);

其中 PTB 表示每个参数都是指向任意长度数组的结构指针。结构体主要包含字符串、双精度数、字符型和短整型。不管怎样,我最终得到了这个 DllImport 语句:

<DllImport(NativeLibraryName, CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Ansi, SetLastError:=True)>
  Public Shared Function TbeAndring(ByVal sAntMoment As Short, _
                   ByVal sAntPU As Short, _
                   <[In]()> ByVal atbpu As PTB_PU(), _
                   <[In]()> ByVal atbandringinfo() As PTB_ANDRING_INFO, _
                   <[In]()> ByVal atbparamsEfter() As PTB_PARAMS, _
                   <[In]()> ByVal aNivaInfoEfter() As PTB_PREMIE_NIVA_INFO, _
                   <[In](), Out()> ByVal atbpremieEfter() As PTB_PREMIE, _
                   <[In]()> ByVal atbFormanInfoEfter() As PTB_FORMAN_INFO, _
                   <[In](), Out()> ByVal atbFormanEfter() As PTB_FORMAN, _
                   <[In](), Out()> ByVal atbfunkEfter() As PTB_FUNK, _
                   <[In]()> ByVal atbparamsFore() As PTB_PARAMS, _
                   <[In]()> ByVal aNivaInfoFore() As PTB_PREMIE_NIVA_INFO, _
                   <[In](), Out()> ByVal atbpremieFore() As PTB_PREMIE, _
                   <[In]()> ByVal atbFormanInfoFore() As PTB_FORMAN_INFO, _
                   <[In](), Out()> ByVal atbFormanFore() As PTB_FORMAN, _
                   <[In](), Out()> ByVal atbfunkFore() As PTB_FUNK) As Int32
  End Function

正如您所看到的,一些参数也被非托管代码更改了。

I've an issue regarding p/invoke from managed to unmanaged code. See my original post at the MSDN forum (as brief summary is seen later in this post). Before I go on, I just want to explain a couple of things: I have a wrapper assembly in net 3.5 that does the actual interop to the unmanaged code. Then I have my console "host app" which uses the wrapper assembly.

The solution I came up (I refer to my MSDN post) works when the host app is using .net 4, but it doesn't work when changing the host app to use .net 3.5. When changing, I get a AccessViolationException.

  • host app: 4.0, wrapper assembly: 3.5
    -> works
  • host app: 3.5, wrapper assembly: 3.5 -> throws
    AccessViolationException

Do anyone have a clue to why I get an AccessViolationException? Most importantly, how do I get it working with .net 3.5?

Brief summary on the MSDN post I refered to. I have this messy p/Invoke I need to solve. The C declaration looks like this:

long TBAPI TbeAndring (short, 
            short,
            PTB_PU,
            PTB_ANDRING_INFO,
            PTB_PARAMS,
            PTB_PREMIE_NIVA_INFO,
            PTB_PREMIE,
            PTB_FORMAN_INFO,
            PTB_FORMAN,
            PTB_FUNK,
            PTB_PARAMS,
            PTB_PREMIE_NIVA_INFO,
            PTB_PREMIE,
            PTB_FORMAN_INFO,
            PTB_FORMAN,
            PTB_FUNK);

Where PTB means that each argument is a struct pointer to an array of arbitrary length. The structs mostly contains strings, doubles, char and short. Anyway, I ended up with this DllImport statement:

<DllImport(NativeLibraryName, CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Ansi, SetLastError:=True)>
  Public Shared Function TbeAndring(ByVal sAntMoment As Short, _
                   ByVal sAntPU As Short, _
                   <[In]()> ByVal atbpu As PTB_PU(), _
                   <[In]()> ByVal atbandringinfo() As PTB_ANDRING_INFO, _
                   <[In]()> ByVal atbparamsEfter() As PTB_PARAMS, _
                   <[In]()> ByVal aNivaInfoEfter() As PTB_PREMIE_NIVA_INFO, _
                   <[In](), Out()> ByVal atbpremieEfter() As PTB_PREMIE, _
                   <[In]()> ByVal atbFormanInfoEfter() As PTB_FORMAN_INFO, _
                   <[In](), Out()> ByVal atbFormanEfter() As PTB_FORMAN, _
                   <[In](), Out()> ByVal atbfunkEfter() As PTB_FUNK, _
                   <[In]()> ByVal atbparamsFore() As PTB_PARAMS, _
                   <[In]()> ByVal aNivaInfoFore() As PTB_PREMIE_NIVA_INFO, _
                   <[In](), Out()> ByVal atbpremieFore() As PTB_PREMIE, _
                   <[In]()> ByVal atbFormanInfoFore() As PTB_FORMAN_INFO, _
                   <[In](), Out()> ByVal atbFormanFore() As PTB_FORMAN, _
                   <[In](), Out()> ByVal atbfunkFore() As PTB_FUNK) As Int32
  End Function

As you see some of the arguments are changed by the unmanaged code as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月无声 2024-10-14 19:20:00

我不知道这是否是 AccessViolationException 的唯一原因,但我发现该异常来自使用损坏的 C 运行时库堆运行的非托管代码。特别是,一些本来包含有效指针的内存实际上包含了垃圾:当取消引用时,它指向不存在的内存。

如果您遇到这样的问题,那么 .NET 版本的更改可能只是转移了该问题,使得该问题已在 .NET 3.5 下出现,但尚未在 .NET 下出现4.0。

我建议在调试器下运行代码,并包括本机代码调试。你可能会发现原来的异常。

I don't know if it's the only reason for AccessViolationException, but I've seen that exception come from unmanaged code that was running with a corrupt C runtime library heap. In particular, some memory which was meant to contain a valid pointer came to contain garbage: when dereferenced, it pointed to nonexistant memory.

If you have an issue like this, then the change in .NET version may simply have moved the problem around, such that the problem has been seen under .NET 3.5 but has not yet been seen under .NET 4.0.

I recommend running the code under the debugger, and including Native code debugging. You may find the original exception.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文