C# 使用 VB6-Dll - AccessViolationException

发布于 2024-10-31 09:53:58 字数 1784 浏览 0 评论 0原文

我尝试在 C# 程序中使用 VB6 DLL。但我总是遇到 AccessViolationException。也许你可以告诉我我做错了什么。 我创建了一个 Test-VB6-DLL,如本教程所示: http://oreilly.com/pub/a/windows/2005 /04/26/create_dll.html

然后我尝试像这篇文章中那样动态使用这个 DLL:

但如果我尝试使用 [DLLImport]。我总是遇到 AccessViolationException。 也许有人可以给我提示。

问候 viktor

P.S.:我能够做的是创建对现有 DLL 的引用。但这种方法有一个缺点,如果更新 DLL,我必须更新所有引用。这将发生(或多或少)开放,因为 dll 是正在开发的软件项目的一部分。也许可以更新引用而无需重新编译 C# 程序?


@MarkJ:不 - 二进制兼容性没有带来成功。

以下是来源: VB6-Dll:

Option Explicit

Public Function Increment(var As Integer) As Integer
   If Not IsNumeric(var) Then Err.Raise 5

   Increment = var + 1
End Function

这里是尝试使用 VB6 Dll 的 C# 代码:

class Program
{

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr LoadLibrary(String DllName);
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr GetProcAddress(IntPtr hModule, byte[] procedureName);
    static void Main(string[] args)
    {
        IntPtr pDll = LoadLibrary(@"P:\dev\Path\to\TestProjekt.dll");

        string x = "Increment";         
        Encoding e = Encoding.GetEncoding("ISO-8859-1");
        byte[] b = e.GetBytes(x);

        IntPtr pAddressOfFunctionToCall = GetProcAddress(pDll, b);
        Increment inc = Increment)Marshal.
                GetDelegateForFunctionPointer(pAddressOfFunctionToCall,
                                              typeof(Increment));

        int a = inc(5);    // <---- Here the AccessViolationException is thrown

        return;
    }
}

与此同时,我已经阅读了我能找到的任何文档,但我仍然不知道为什么这不起作用grgrgrgrgr

问候 维克多

I try to use a VB6 DLL in a C# Program. But I allways get a AccessViolationException. Maybe you can tell me what Im doing wrong.
I created a Test-VB6-DLL like in this tutorial:
http://oreilly.com/pub/a/windows/2005/04/26/create_dll.html

Then I tried to use this DLL dynamically like in this Post:
http://blogs.msdn.com/b/jonathanswift/archive/2006/10/03/dynamically-calling-an-unmanaged-dll-from-.net-_2800_c_23002900_.aspx?PageIndex=3#comments

But also if I try it by using [DLLImport]. I allways run into the AccessViolationException.
Maybe someone can give me a hint.

regards
viktor

P.S.: What I was able to do is to create a reference to an existing DLL. But this approach has the disadvantage, that I have to update all the references if the DLL is updated. And this will happen (more or less) open because to dlls are part of a softwareproject that is under developmen. Maybe there is a possibility to update the references without to need to recompile the C# program?


@MarkJ: No - binary compatibility brought no success.

Here are the sources:
The VB6-Dll:

Option Explicit

Public Function Increment(var As Integer) As Integer
   If Not IsNumeric(var) Then Err.Raise 5

   Increment = var + 1
End Function

And here the C# code that tries to use the VB6 Dll:

class Program
{

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr LoadLibrary(String DllName);
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr GetProcAddress(IntPtr hModule, byte[] procedureName);
    static void Main(string[] args)
    {
        IntPtr pDll = LoadLibrary(@"P:\dev\Path\to\TestProjekt.dll");

        string x = "Increment";         
        Encoding e = Encoding.GetEncoding("ISO-8859-1");
        byte[] b = e.GetBytes(x);

        IntPtr pAddressOfFunctionToCall = GetProcAddress(pDll, b);
        Increment inc = Increment)Marshal.
                GetDelegateForFunctionPointer(pAddressOfFunctionToCall,
                                              typeof(Increment));

        int a = inc(5);    // <---- Here the AccessViolationException is thrown

        return;
    }
}

In the meantime I have read any doc I could find but still I don't habe any idea why this ist not working grgrgrgrgr

regards
viktor

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

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

发布评论

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

评论(1

萝莉病 2024-11-07 09:53:58

您的 byte[] b 没有终止 null,因此不是有效的非托管 LPCSTR。我不明白为什么您要尝试手动编码方法名称,而不是像这样声明 GetProcAddress 并让框架互操作代码为您处理编组:

public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procedureName);

您必须检查返回值 (pAddressOfFunctionToCall )。当它是IntPtr.Zero时,正如我相信您所得到的那样,因为您的GetProcAddress的lpProcName参数是错误的,那么尝试通过其委托包装器调用将始终给出一个AccessViolationException

另外,完成后不要忽略在模块句柄上调用 FreeLibrary

Your byte[] b has no terminating null, so isn't a valid unmanaged LPCSTR. I don't understand why you are fiddling about trying to encode the method name by hand, instead of declaring GetProcAddress like this and having the Framework interop code take care of the marshalling for you:

public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procedureName);

You must check the return value (pAddressOfFunctionToCall). When it isIntPtr.Zero as I believe you are getting, because your lpProcName argument to GetProcAddress is wrong, then attempting to call through its Delegate wrapper will always give an AccessViolationException.

Also, don't omit to call FreeLibrary on the module handle when you are done.

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