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

C# 调用vb6 COM dll函数时,C GetProcAddress返回0,c#,com,vb6,marshalling,com-interop,C#,Com,Vb6,Marshalling,Com Interop,我有一个vb6 COM dll,里面有一个LoginClass类和一个LoginUser函数。我需要从C动态调用此vb6 COM dll。我尝试在C代码下动态访问它,但GetProcAddress返回0,即使在LoadLibrary返回指针之后也是如此 static class NativeMethods { [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)] public static

我有一个vb6 COM dll,里面有一个LoginClass类和一个LoginUser函数。我需要从C动态调用此vb6 COM dll。我尝试在C代码下动态访问它,但GetProcAddress返回0,即使在LoadLibrary返回指针之后也是如此

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;
 }
}

无论何时尝试pinvoke DLL中的函数,首先在DLL上运行dumpbin.exe/exports。从Visual Studio命令提示符执行此操作。它显示DLL导出的函数的名称

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

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


如果不知道这些对象的外观,请单击“解决方案资源管理器”窗口中的“显示所有文件”图标,打开“引用”节点,右键单击COM服务器,然后选择“在对象浏览器中显示”。IntelliSense将进一步帮助您成功。

您不能像那样调用VB6库,它不会导出任何可以导入的C风格函数。看看。这是否意味着不能从C动态调用vb6 COM dll。不,您可以始终通过COM互操作调用它们,只是不能DllImport它或多或少相当于LoadLibrary+GetProcAddress导出函数,因为实际上没有C风格的导出函数。