我将花一点时间解释我的项目结构:
三个dll:
- mclController.dll - 用 C# 编写的用于控制硬件的第三方 dll。
- MCLWrapper.dll - 我用 C# 编写了这个 ll,这样它将作为 COM 工作,将 mclControl.dll 公开给原生 C++ dll。
- ThorDetectorSwitch.dll - 我用本机 C++ 编写了这个 dll。
结构:
- ThorDetectorSwitch.dll 调用包装 mclController.dll 的 MCLWrapper.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 的构造函数已编辑!于 2013 年 6 月 15 日,中部时间 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;
}
生成 COM 对象的 MCLWrapper
// 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
是回报;
一些补充
- 我一直被告知这是因为
CoInitialized()
没有被调用,这就是原因,但我觉得这不是原因,因为这个 ThorDetectorSwitch.dll 与另一个应用程序完美配合,我相信我已经调用CoInitialized()
了我的代码。 - 我已经注册了我的 MCLWrapper.dll
regasm MCLWrapper.dll /tlb:MCLWrapper.tlb /codebase
- 调试器输出:“尝试在 OS 加载程序锁内进行托管执行。不要尝试在 DllMain 或图像初始化函数内运行托管代码,因为这样做会导致应用程序挂起。”
所以现在我不知道我应该往哪个方向走,而且我已经为这个问题苦苦挣扎了好几天。所以我真的希望有人能给我一些指点。谢谢!