c # — CoCreateInstance () -858993460 (в comip.h) Переполнение стека

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

Есть три библиотеки:

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

Состав:

  • ThorDetectorSwitch.dll вызывает MCLWrapper.dll, который оборачивает mclController.dll.
  • Я реализую небольшое тестовое консольное приложение на C ++, TDSTest.exe для вызова ThorDetecttorSwitch.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 Editted! 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 или образа, так как это может привести к зависанию приложения».

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

1

Решение

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

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]