C# Using VB6-Dll - AccessViolationException

本文关键字:AccessViolationException VB6-Dll Using | 更新日期: 2023-09-27 17:49:24

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

然后我尝试像在这篇文章中动态地使用这个DLL:http://blogs.msdn.com/b/jonathanswift/archive/2006/10/03/dynamically-calling-an-unmanaged-dll-from-.net-_2800_c_23002900_.aspx?PageIndex=3评论

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

的问候维克多

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


@MarkJ: No - binary compatibility没有成功。

来源如下: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

的问候维克多

C# Using VB6-Dll - AccessViolationException

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

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

必须检查返回值(pAddressOfFunctionToCall)。当它是IntPtr.Zero,因为我相信你得到,因为你的lpProcName参数GetProcAddress是错误的,然后试图通过它的委托包装调用将始终给出一个AccessViolationException

另外,当您完成时,不要忽略调用模块句柄上的FreeLibrary