C# 使用 VB6-Dll - AccessViolationException
我尝试在 C# 程序中使用 VB6 DLL。但我总是遇到 AccessViolationException。也许你可以告诉我我做错了什么。 我创建了一个 Test-VB6-DLL,如本教程所示: http://oreilly.com/pub/a/windows/2005 /04/26/create_dll.html
然后我尝试像这篇文章中那样动态使用这个 DLL:
但如果我尝试使用 [DLLImport]。我总是遇到 AccessViolationException。 也许有人可以给我提示。
问候 viktor
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
问候 维克多
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 have 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的
byte[] b
没有终止 null,因此不是有效的非托管LPCSTR
。我不明白为什么您要尝试手动编码方法名称,而不是像这样声明 GetProcAddress 并让框架互操作代码为您处理编组:您必须检查返回值 (
pAddressOfFunctionToCall )。当它是
IntPtr.Zero
时,正如我相信您所得到的那样,因为您的GetProcAddress
的lpProcName参数是错误的,那么尝试通过其委托包装器调用将始终给出一个AccessViolationException
。另外,完成后不要忽略在模块句柄上调用
FreeLibrary
。Your
byte[] b
has no terminating null, so isn't a valid unmanagedLPCSTR
. 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:You must check the return value (
pAddressOfFunctionToCall
). When it isIntPtr.Zero
as I believe you are getting, because your lpProcName argument toGetProcAddress
is wrong, then attempting to call through its Delegate wrapper will always give anAccessViolationException
.Also, don't omit to call
FreeLibrary
on the module handle when you are done.