C#GetProcAddress在调用vb6 COM dll函数时返回0

时间:2013-07-01 07:29:41

标签: c# com vb6 marshalling com-interop

我有一个带有类LoginClass和一个函数LoginUser的vb6 COM dll。我需要从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;
 }
}

1 个答案:

答案 0 :(得分:2)

每当您尝试在DLL中调用函数时,首先在DLL上运行dumpbin.exe / exports。从Visual Studio命令提示符执行此操作。它显示了DLL导出的函数的名称。

在这种情况下,非常可能只会看到4个导出的函数,即任何与自动化兼容的COM服务器导出的函数。 DllGetClassObject,DllRegisterServer,DllUnregisterServer和DllCanUnloadNow。你会看到LoginUser。 DllUn / RegisterServer由Regsvr32.exe调用,仅用于从注册表注册和删除服务器。 DllCanUnloadNow是Windows调用的函数,用于检查DLL是否可以从内存中卸载。 DllGetClassObject是大狗,它是类工厂函数并创建对象。使用任何COM服务器的必要起点是首先创建一个对象。然后你可以调用该对象的方法,其中一个无疑被命名为LoginUser。

要在VB.NET代码中使用这样的COM服务器,请从Project + Add Reference开始。单击“浏览”选项卡或按钮,然后导航到DLL。 Visual Studio将读取嵌入在DLL中的类型库,它包含服务器实现的对象和接口的声明。假设VB6 dll名为“foo.dll”,您将在构建目录中获得Interop.Foo.dll文件。将此程序与您的程序以及COM服务器的安装程序一起发送,因此它也可以在用户的​​计算机上运行。

如果您不知道这些对象是什么样的,请单击Solution Explorer窗口中的Show All Files图标,打开References节点,右键单击您的COM服务器并选择Show in Object Browser。 IntelliSense将进一步帮助您陷入成功之中。