我尝试在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
问候 尤
答案 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
。