从 .NET 调用 DLL 时出现问题

发布于 2025-01-03 19:35:00 字数 726 浏览 0 评论 0原文

我有一个 VB6 DLL,它包装了对第三方组件的调用。当我从 VB6 调用我的 DLL 时,一切正常,但是当我从 vb.net(针对 2.0 框架 - VS2010)调用它时,我收到此错误:

发生AccessViolationException

尝试读取或写入受保护的内存。这通常是一个 表明其他内存已损坏。

此错误仅发生在 Windows 7 上(Windows XP 客户端工作正常)。

我查了一下,我发现的所有文章都谈到声明不正确。不过,我没有声明任何 API 调用,第 3 方组件已提前绑定在我的 VB6 DLL 中。我可以运行 DLL,设置断点,然后它进入我的 VB6 函数,但在调用第 3 方组件中的函数时出错。

我的 VB6 DLL 采用 3 个字符串和 1 个 32 位数字(VB6 中为 long)参数。我调用的第 3 方的 DLL 函数采用一个字符串(bstrDNSID 作为字符串,是 Intellisense 在 VB6 中显示的内容)。这就是出错的地方。

有谁知道如何解决这个问题?

更新: 所有编组都没有帮助,因此我尝试在 VB6 DLL 中创建一个测试子程序。我对 DLL 的测试子中的所有值进行了硬编码。从 VB6 调用时它工作正常,但从 .NET 运行时会出现与上面相同的错误。另外有趣的是,当我从 VB6 IDE 运行 VB6 DLL 时,从 .NET 调用 DLL 时不会出现错误。

I have a VB6 DLL that wraps a call to a 3rd party component. When I call my DLL from VB6, everything works fine, but when I call it from vb.net (2.0 framework targeted - VS2010) I get this error:

AccessViolationException occurred

Attempted to read or write protected memory. This is often an
indication that other memory is corrupt.

This error only occurs on Windows 7 (Windows XP clients work fine).

I've looked this up and all the articles I found talked about the declaration not being correct. I am not declaring any APIs calls though, the 3rd party component is early bound in my VB6 DLL. I can run the DLL, set a breakpoint, and it goes into my VB6 function, but errors calling a function in the 3rd party component.

My VB6 DLL takes 3 string and one 32bit numeric (long in VB6) parameters. The 3rd party's DLL function that I am calling is taking a string (bstrDNSID as string is what Intellisense shows in VB6). This is where it errors.

Does anyone know how this might be resolved?

Update:
None of the marshalling has helped, so I tried creating a test sub in my VB6 DLL. I hardcoded all the values within the DLL's test sub. It works fine when called from VB6, but gives the same error as above when running from .NET. Also of interest, when I have the VB6 DLL running from the VB6 IDE, I do not get the error when calling the DLL from .NET.

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

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

发布评论

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

评论(3

太傻旳人生 2025-01-10 19:35:00

这并不能真正回答你的问题,但我无法在评论中加入这些例子。

当将字符串编组到来自 .NET 的非托管 DLL 调用时,我有时会收到 AccessViolationException,因为我没有指定正确的字符集。我通过将 IntPtr 显式转换为我需要的字符集中的字符串来修复它。

[DllImport("MyDLL.dll", CharSet = CharSet.Ansi)]
static extern void do_something(IntPtr str);

void DoSomethingWrapper(string str) {
    var ptr = Marshal.StringToHGlobalAnsi(str);
    do_something(ptr);
}

您可能需要Marshal.StringToBSTR。我不知道是否可以使用指针调用 VB6 函数,或者是否必须在 VB6 DLL 中创建指针。

这是您可能会发现有用的问题:如何获取字符集正在使用VB6?

This doesn't really answer your question, but I couldn't fit these examples in the comments.

When marshaling strings to unmanaged DLL calls from .NET, I would receive an AccessViolationException on occasion because I wasn't specifying the right charset. I fixed it by explicitly converting an IntPtr to a string in the charset I needed.

[DllImport("MyDLL.dll", CharSet = CharSet.Ansi)]
static extern void do_something(IntPtr str);

void DoSomethingWrapper(string str) {
    var ptr = Marshal.StringToHGlobalAnsi(str);
    do_something(ptr);
}

You might need Marshal.StringToBSTR. I don't know if you can call the VB6 function with a pointer or if you'll have to create the pointer in the VB6 DLL.

Here's a question you might find useful: How can I get the charset VB6 is using?

浊酒尽余欢 2025-01-10 19:35:00

解决方法:

我找到了一种有效的解决方案。我只是在 VB6 中创建了一个名为第 3 方组件的 ActiveX EXE。就像 .NET 的魅力一样。

另外值得注意的是,我从未创建过 ActiveX EXE,也不知道 regsvr32 无法注册它。 这里是注册 ActiveX EXE 的正确方法。

Workaround:

I have found one solution that works. I simply created an ActiveX EXE in VB6 that called the 3rd party component. Works like a charm from .NET.

Also of note, I'd never created an ActiveX EXE and didn't know that regsvr32 will not work to register it. Here is the proper way to register ActiveX EXEs.

旧梦荧光笔 2025-01-10 19:35:00

VB6 可能将整数声明为 16 位。从 VBA 调用 DLL 也会出现这个问题。解决方案应该是将您的整数更改为 long

VB6 probably declares integer as 16 bit. This is a problem with calling DLLs from VBA too. The solution should be to change your integer to long

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