2011-04-08 52 views
1

我嘗試在C#程序中使用VB6 DLL。但我總是得到一個AccessViolationException。也許你可以告訴我我做錯了什麼。 我創建了一個測試,VB6的DLL一樣在本教程: http://oreilly.com/pub/a/windows/2005/04/26/create_dll.htmlC#使用VB6-DLL - AccessViolationException

然後我試圖用這個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

關於 viktor

+0

我忘了提及:我正在使用.Net 3.5 ;-) – viktor 2011-04-08 20:38:25

+1

你做錯了。你的問題完全不可能出現錯誤,你沒有發佈任何代碼片段。 – 2011-04-08 22:11:45

+1

您可能需要在VB6 dll項目中使用二進制兼容 – MarkJ 2011-04-09 10:40:12

回答

1

您的byte[] b沒有終止空,因此不是有效的非託管LPCSTR。我不明白爲什麼你擺弄,而不是宣佈GetProcAddress的這樣和具有互操作框架代碼照顧編組爲大家介紹嘗試手工編碼方法名,:

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

您必須檢查返回值(pAddressOfFunctionToCall)。當它是IntPtr.Zero,因爲我相信你會得到,因爲你的GetProcAddress的lpProcName參數是錯誤的,那麼試圖通過它的Delegate包裝器調用將總是給出AccessViolationException

另外,完成後請勿在模塊手柄上調用FreeLibrary

+0

我已將刪除答案中的錯誤代碼放入問題中。它實際上是一個刪除答案的主持人,而不是OP。不知道爲什麼。 – MarkJ 2011-04-13 19:25:37

+0

@MarkJ:謝謝。我相應地編輯了我的答案。 – 2011-04-13 21:15:41

相關問題