C#使用VB6-Dll - AccessViolationException

时间:2011-04-08 20:36:06

标签: c# vb6 dllimport access-violation

我尝试在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#comments

但是如果我通过使用[DLLImport]来尝试​​它。我总是遇到AccessViolationException。 也许有人可以给我一个提示。

问候 尤

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

问候 尤

1 个答案:

答案 0 :(得分:1)

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

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

您必须检查返回值(pAddressOfFunctionToCall)。当我认为你得到IntPtr.Zero时,因为GetProcAddress的lpProcName参数是错误的,那么尝试通过它的Delegate包装器调用将始终给出AccessViolationException

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