调用vb6 COM dll函数时,C#GetProcAddress返回0
本文关键字:C#GetProcAddress 返回 函数 vb6 COM dll 调用 | 更新日期: 2023-09-27 18:20:35
我有一个vb6 COM dll,里面有一个类LoginClass和一个函数LogiUser。我需要从C#动态调用这个vb6 COM dll。我尝试在C#代码下面动态访问它,但即使在LoadLibrary返回指针之后,GetProcAddress仍返回0。
static class NativeMethods
{
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32")]
public static extern bool FreeLibrary(IntPtr hModule);
}
class COMCommands
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate string Login(string userName, string Password, bool Result);
public string CallLoginCommand(string UserName, string Password, ref bool Result)
{
IntPtr pDll = NativeMethods.LoadLibrary(@"D:'MyCOMdll.dll");
IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "LoginUser");
Login CallLogin = (Login)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(Login));
string theResult = CallLogin(UserName, Password, Result);
bool result = NativeMethods.FreeLibrary(pDll);
return theResult;
}
}
每当您尝试在DLL中查找函数时,请首先在DLL上运行dumpbin.exe/exports。从Visual Studio命令提示符执行此操作。它显示DLL导出的函数的名称。
在这种情况下,很可能只会看到4个导出的函数,即任何与Automation兼容的COM服务器导出的函数。DllGetClassObject、DllRegisterServer、DllUnregisterServer和DllCanUnloadNow。您将不会看到LogiUser。DllUn/RegisterServer由Regsvr32.exe调用,仅用于注册服务器和从注册表中删除服务器。DllCanUnloadNow是Windows调用的一个函数,用于检查是否可以从内存中卸载DLL。DllGetClassObject是一个大狗,它是一个类工厂函数,用于创建对象。使用任何COM服务器的一个必要起点是首先创建一个对象。然后您可以调用该对象上的方法,其中一个方法无疑命名为LogiUser。
若要在VB.NET代码中使用这样的COM服务器,请从Project+添加引用开始。单击"浏览"选项卡或按钮,然后导航到DLL。Visual Studio将读取嵌入DLL中的类型库,它包含服务器实现的对象和接口的声明。假设VB6 dll名为"Foo.dll",您将在构建目录中获得一个Interop.Foo.dll文件。将其与程序以及COM服务器的安装程序一起发送,这样它也可以在用户的计算机上运行。
如果不知道这些对象的外观,请单击"解决方案资源管理器"窗口中的"显示所有文件"图标,打开"引用"节点,右键单击COM服务器,然后选择"在对象浏览器中显示"。IntelliSense将进一步帮助您陷入成功的深渊。