2013-07-01 1 views
0

У меня есть dll vb6 COM с классом LoginClass и функцией LoginUser в нем. Мне нужно, чтобы динамически вызывал эту vb6 COM dll с C#. Я пытаюсь использовать код C# для доступа к нему динамически, но GetProcAddress возвращает 0 даже после указателя, возвращаемого LoadLibrary.C# GetProcAddress Возвращает 0 при вызове функции dll vb6 COM d12

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

Вы ** не можете ** вызывать библиотеку VB6 как это, она ** не экспортирует никакой функции «C style» **, которую вы можете импортировать. Взгляните на [эту ссылку] (http://stackoverflow.com/questions/2257883/using-a-vb6-class-in-c-sharp). –

+0

Означает ли это, что dll vb6 COM нельзя динамически вызывать из C#. –

+1

Нет, вы всегда можете ** называть их через COM-интерфейс **, вы просто ** не можете DllImport ** (он более или менее эквивалентен LoadLibrary + GetProcAddress) экспортированной функции (фактически потому, что ** нет стиля C экспортированная функция **). –

ответ

2

Когда вы пытаетесь вызвать функцию в DLL, сначала запустите dumpbin.exe/exports в DLL. Сделайте это из командной строки Visual Studio. Он показывает вам имена функций, экспортируемых DLL.

В этом случае очень Вероятно, вы увидите только 4 экспортированные функции, которые экспортируются любым совместимым с COM-совместимым COM-сервером. DllGetClassObject, DllRegisterServer, DllUnregisterServer и DllCanUnloadNow. И вы будете не см. LoginUser. DllUn/RegisterServer вызывается Regsvr32.exe, используется только для регистрации и удаления сервера из реестра. DllCanUnloadNow - это функция, вызываемая Windows, чтобы проверить, можно ли выгрузить DLL из памяти. DllGetClassObject - большая собака, это класс фабрика функция и создает объекты. Необходимой отправной точкой для использования любого COM-сервера является создание объекта в первую очередь. Затем вы можете вызывать методы на этом объекте, один из которых, без сомнения, называется LoginUser.

Чтобы использовать COM-сервер, подобный этому в коде VB.NET, начните с Project + Add Reference. Нажмите вкладку Обзор или кнопку и перейдите к DLL. Visual Studio будет читать библиотеку типа, которая встроена в DLL, содержит декларации объектов и интерфейсов, реализованных сервером. Вы получите файл Interop.Foo.dll в каталоге сборки, предполагая, что dll VB6 называется «foo.dll». Передайте это вместе с вашей программой, а также установщик для COM-сервера, чтобы он работал и на вашем компьютере пользователя.

Если вы не представляете, как выглядят эти объекты, щелкните значок «Показать все файлы» в окне «Обозреватель решений», откройте узел «Ссылки», щелкните правой кнопкой мыши ваш сервер COM и выберите «Показать в обозревателе объектов». IntelliSense также поможет вам упасть в яму успеха.

 Смежные вопросы

  • Нет связанных вопросов^_^