开发者

C# Using VB6-Dll - AccessViolationException

开发者 https://www.devze.com 2023-02-23 07:10 出处:网络
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 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 hav开发者_运维技巧e 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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号