1

プロジェクトの構造について少し説明します。

3 つの dll があります。

  1. mclController.dll - ハードウェアを制御するために C# で記述されたサード パーティの dll。
  2. MCLWrapper.dll - この ll を C# で記述して、mclControl.dll をネイティブ C++ dll に公開する COM として機能するようにしました。
  3. ThorDetectorSwitch.dll - この dll はネイティブ C++ で作成しました。

構造:

  • ThorDetectorSwitch.dll は、mclController.dll をラップする MCLWrapper.dll を呼び出します。
  • 私は、ThorDetectorSwitch.dll を呼び出すために、C++ で小さなテスト コンソール アプリケーション TDSTest.exe を実装しています。

したがって、基本的には次のように機能します: TDSTest.exe -> ThorDetectorSwitch.dll -> MCLWrapper -> mclController.dll

いくつかのコード:

- TDSTest.exe (x64 構成でビルドされた Windows コンソール アプリケーション) が 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リターンです。

いくつかの追加

  1. が呼び出されなかったことが原因であると言われ続けていますが、それがCoInitialized()理由ですが、この ThorDetectorSwitch.dll は別のアプリケーションで完全に正常に動作CoInitialized()し、自分のコードで呼び出したと信じているため、それが理由ではないと感じています。
  2. MCLWrapper.dll を登録しましたregasm MCLWrapper.dll /tlb:MCLWrapper.tlb /codebase
  3. デバッガー出力: 「OS ローダー ロック内でマネージ実行を試みています。アプリケーションがハングする可能性があるため、DllMain またはイメージ初期化関数内でマネージ コードを実行しようとしないでください。」

だから今、私はどの方向に進むべきか分からず、何日もこの問題に苦しんでいます. だから、誰かが私にいくつかの指針を与えることができることを本当に願っています. ありがとう!

4

1 に答える 1

2

DLL の読み込み時に作成されるグローバル変数としてオブジェクトを作成するのではなく、オブジェクトを遅延構築する必要があります。

Initialize()クライアントによって呼び出される関数をDLL に提供させることはできますか? もちろん、オブジェクトを「まったくグローバルではない」ようにできないと仮定します。

于 2013-06-18T16:52:50.903 に答える