CoCreateInstance() -858993460 (в comip.h) С++

Я потрачу немного времени на объяснение структуры моего проекта:

Есть три dll:

  1. mclController.dll — сторонняя dll, написанная на C# для управления оборудованием.
  2. MCLWrapper.dll — я написал эту ll на C#, так что она будет работать как COM для предоставления mclControl.dll собственной dll C++.
  3. ThorDetectorSwitch.dll — я написал эту dll на родном C++.

Структура:

  • ThorDetectorSwitch.dll вызывает MCLWrapper.dll, который является оболочкой mclController.dll.
  • Я реализую небольшое тестовое консольное приложение на C++, TDSTest.exe для вызова ThorDetectorSwitch.dll.

В основном это работает следующим образом: TDSTest.exe -> ThorDetectorSwitch.dll -> MCLWrapper -> mclController.dll

Некоторый код:

-Как TDSTest.exe (консольное приложение Windows, созданное с конфигурацией x64) вызывает ThorDetectorSwitch.dll:

#include "stdafx.h"    
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <math.h>
#include <windows.h>
#include "TDSTest.h"

typedef long (*TDSFindDevices)(long&);
typedef long (*TDSGetParam)(const long, double&);
typedef long (*TDSTeardownDevice)();
typedef long (*TDSStartPosition)();

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
        if (argc < 2) 
        {
             cout<<"This is ThorDetecttorSwitch test program."<<endl;
             return 1;  
        }   

        HINSTANCE hInst = LoadLibrary(_T(".\\Modules_Native\\ThorDetectorSwitch.dll"));

        if( hInst == NULL )
        {
            DWORD err = GetLastError();
            cout<<"Error loading ThorDetectorSwitch.dll. Program exiting..."<<endl;
            return 1;
        }

}

- Конструктор ThorDetectorSwitch.dll ОТРЕДАКТИРОВАНО! 15.06.2013, Центральное время 19:41

ThorDetectorSwitch::ThorDetectorSwitch() :_mcSwitch(ComHelper(__uuidof(MCLControlClass)))
{
    CoInitialize(NULL);
    MCLWrapper::MCLControlPtr mclSmartPtr;
    HRESULT hr = CoCreateInstance(__uuidof(MCLWrapper::MCLControlClass), NULL, CLSCTX_ALL, __uuidof(MCLWrapper::MCLControl), (void**)&mclSmartPtr); // program breaks right here!!!
    _mcSwticth = mclSmartPtr;

    _A  = WstringToBSTR(L"A"); 
    _B  = WstringToBSTR(L"B");
    _C  = WstringToBSTR(L"C");
    _D  = WstringToBSTR(L"D");

    _deviceDetected = FALSE;
}

MCLWrapper, создающий COM-объект

// C# COM wrapper 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using mcl_RF_Switch_Controller64;
using System.Runtime.InteropServices;
// for function reference see miniCircuit RF controller manual

namespace MCLWrapper
{
    [Guid("7C312A7C-2E77-4de7-A76F-990F268AB818")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface MCLControl
    {
        [DispId(1)]
        void Connect(string SerialNumber);

        [DispId(2)]
        void Set_Switch(string SwitchName, int Val);

        [DispId(3)]
        void Set_SwitchesPort(byte binVal);

        [DispId(4)]
        void GetSwitchesStatus(int statusRet);

        [DispId(5)]
        void Disconnect();
    };

    [Guid("BEC33A1D-BB98-4332-B326-92D480ECC246"), 
    ClassInterface(ClassInterfaceType.None)]
    public class MCLControlClass : MCLControl
    {
        private USB_RF_SwitchBox _sb = new USB_RF_SwitchBox();

        public void Connect(string SerialNumber)
        {
            _sb.Connect(ref SerialNumber);
        }

        public void Set_Switch(string SwitchName, int Val)
        {
            _sb.Set_Switch(ref SwitchName, ref Val);
        }

        public void Set_SwitchesPort(byte binVal)
        {
            _sb.Set_SwitchesPort(ref binVal);
        }

        public void GetSwitchesStatus(int statusRet)
        {
            _sb.GetSwitchesStatus(ref statusRet);
        }

        public void Disconnect()
        {
            _sb.Disconnect();
        }
    }
}

Моя проблема:

Когда TDSTest выполняется, он сначала попадает

HINSTANCE hInst = LoadLibrary(_T(".\\Modules_Native\\ThorDetectorSwitch.dll"));

затем он прерывается на: hr = CoCreateInstance(......) в ThorDetectorSwitch.cpp

hr = -858993460 — возврат;

Несколько дополнений

  1. Мне постоянно говорят, что это произошло из-за того, что CoInitialized() не вызывался, и это причина, но я чувствую, что это не причина, потому что ThorDetectorSwitch.dll прекрасно работает с другим приложением, и я полагаю, что вызвал CoInitialized() в своем коде .
  2. Я зарегистрировал свою MCLWrapper.dll с помощью regasm MCLWrapper.dll /tlb:MCLWrapper.tlb /codebase
  3. Вывод отладчика: «Попытка управляемого выполнения внутри блокировки загрузчика ОС. Не пытайтесь запускать управляемый код внутри функции инициализации DllMain или образа, поскольку это может привести к зависанию приложения».

Так что прямо сейчас я понятия не имею, в каком направлении мне идти, и я боролся с этой проблемой в течение нескольких дней. Поэтому я очень надеюсь, что кто-то может дать мне несколько советов. Спасибо!


person Nick X Tsui    schedule 14.06.2013    source источник
comment
1) -858993460 не является корректной ошибкой COM (уже объяснил что и почему). 2) При сбое приложения вы получаете исключение, и если да, то какое? 3) Приложение не работает во время вызова CoCreateInstance() - я уже упоминал об этом. Это указывает на то, что с вашей оболочкой что-то не так, но, поскольку я не специалист по С#, я не собираюсь догадываться, что именно.   -  person Captain Obvlious    schedule 15.06.2013
comment
возможный дубликат значения структуры не сохраняются, значения изменены на -858993460   -  person Hans Passant    schedule 15.06.2013
comment
@HansPassant Кажется, что-то не инициализируется в моем коде. Это то, что я пытаюсь понять.   -  person Nick X Tsui    schedule 15.06.2013
comment
@CaptainObvlious Когда интеллектуальный указатель COM инициируется, он переходит вправо к CoCreateInstance(), где происходит сбой. Перед инициацией интеллектуального указателя вызывается CoInitialize(). Я разместил здесь весь код оболочки, я понятия не имею, где я ошибся в обертке.   -  person Nick X Tsui    schedule 16.06.2013
comment
@NickXTsui Вы до сих пор не сказали нам, как это терпит неудачу. Это терпит неудачу с исключением. Если это не удается с исключением, знание того, какое исключение полезно. Сокращение примера таким образом, что весь соответствующий код C++ для создания COM-объекта находится в main(), также помогает локализовать проблему. На самом деле я предлагаю вам вызывать CoCreateInstance напрямую вместо использования _com_ptr_t. Пока вы не сделаете эти вещи, у меня нет дальнейших комментариев.   -  person Captain Obvlious    schedule 16.06.2013
comment
@CaptainObvlious Я немного отредактировал конструктор, так что теперь он выглядит проще. Я не думаю, что заметил какие-либо исключения, он просто прерывается на CoCreateInstance(); Кроме того, я обнаружил в своем выводе отладчика это сообщение «Попытка управляемого выполнения внутри блокировки загрузчика ОС». Не пытайтесь запускать управляемый код внутри функции инициализации DllMain или изображения, так как это может привести к зависанию приложения. Я отключил блокировку загрузчика, но на самом деле ничего не изменилось.   -  person Nick X Tsui    schedule 16.06.2013
comment
... Вы используете глобальный объект ThorDetectorSwitch? Потому что если да, конструктор будет вызываться из _DllMainCrtStartup()...   -  person Medinoc    schedule 18.06.2013
comment
-858993460 = 0xCCCCCCCC, что означает вы получили доступ к неинициализированной памяти   -  person phuclv    schedule 18.08.2018


Ответы (1)


Вам нужно лениво построить свой объект, а не использовать его как глобальную переменную, созданную при загрузке DLL.

Может быть, вы могли бы сделать так, чтобы ваша DLL предоставляла функцию Initialize(), которую вызывал бы клиент? Предполагая, что вы, конечно, не можете сделать свой объект «вообще не глобальным».

person Medinoc    schedule 18.06.2013