2012-04-09 15 views
0

私はそれに機能を追加するために、いくつかのソフトウェアにプラグインするために、特定のインターフェイスを称えるDLLの作成が含まれたプロジェクトに取り組んでいます。これは私のdllを呼び出すdllによって行われます(私は呼び出しを行うdllのソースコードを持っていません)。もともと私は、COM可視DLLを作成したインタフェースとC#実装を与えられました。しかし、これをしばらく使用した後、私はいくつかの大きなC++ライブラリを使いたいと思っていました。ラッパーの作成には長い時間がかかりました。代わりにC++ ATL COM dllを作成することを考えました。私はこれを行い、私のクラスのメソッドが正しく呼び出されるように見える(私はDLLを登録し、プログラムを実行し、メソッドは正しい順序で呼び出されるように見える)が、私はいくつかの動作が異なっていることがわかった。C#とC++のDLLの動作が異なるのはなぜですか?

私は私のコードは、クローズドソースのAPIに関連するとして、これを説明するに取り掛かるするかどうかはわかりませんが、私は例を記述した場合、おそらく誰かが私が見て欲しいかもしれない場所へといくつかのアイデアを持っているかもしれません。例えば

、C#のDLLに私はこれを行うことによって、ファイルを開こう:

FMANFileControl fileControl = new FMANFileControl(); 
FMANFile wFile = null; 
const string filePath = @"C:\Data\April 4\Data_IDA.wiff"; 
wFile = fileControl.GetFileObject(filePath, 1); 
long numSamples = wFile.GetNumberOfSamples(); 

私はサンプルの正確な数を取得します。 (コード短いを維持するために、削除HRESULTチェックの一部で)私はこれを持って私のC++ DLL内

std::string filePath = "C:\\Data\\April 4\\Data_IDA.wiff"; 
_bstr_t fileName(filePath.c_str()); 
IFMANFilePtr ipFMANFile; 
IFMANFileControlPtr ipFMANFileControl; 
hr = ipFMANFileControl.CreateInstance(__uuidof(FMANFileControl)); 
hr = ipFMANFile.CreateInstance(__uuidof(FMANFile)); 
ipFMANFile = ipFMANFileControl->GetFileObject(fileName, 1); 
long numSamples = ipFMANFile->GetNumberOfSamples(); 

が、ファイルはゼロサンプルで、その結果、正常に開きません。

[id(0x00000001), helpstring("method GetWiffFileObject")] 
IFMANWiffFile* GetWiffFileObject([in] BSTR WiffFileName, [in] long sample); 

私はから情報を取得するファイルは、実験中に書き込まれているものであり、それはそれをより多くのデータを取得する直前に:私はタイプライブラリを見て、それが機能するためにこれを言うOLEVIEWを使用して

私のメソッドを呼び出し、私は最新のファイルを取得することができるはずです。 C#のdllではこれが可能ですが、C++のdllではそうではありません。私はこれの詳細が隠されて実現している間、私は疑問に思って、誰もが同じDLLによって呼び出されたときに同じインターフェイスを利用するC++のCOM DLLとC#の、のComVisible DLLが異なるbehavourを示すであろう理由を任意のアイデアを持っています。

私は現時点ではかなり困惑していますので、すべての任意のアイデアは、彼らが道オフベースであることが判明した場合でも、高く評価されるだろう。もし誰かが助けてくれると思ったら、私はソースコードを共有することができます。

EDIT: 私は、しかし、私は私のコードをコンパイルすることができませんでした、1に答えるために解決策を試してみました。 Differences between [in, out] and [out, retval] in COM IDL definitions FMANFileポインタがマークされているので、[アウト、retval]作業方法になることをすることを示唆しているようだ:

IFMANFilePtr ExploreData::IFMANFileControl(BSTR filename, long sample); 

するか、私はその記事を誤って解釈していますこれについて読むとき、私はこの記事を見つけましたか?

EDIT 2:私は、なぜ本当にわからないけれども は作業それを手に入れました。もともと私は、このようなクラスのプライベートメンバ変数としてヘッダで宣言された変数、持っていた :ちょうどそれを試して

class ATL_NO_VTABLE CUserIDA : 
public CComObjectRootEx<CComSingleThreadModel>, 
public CComCoClass<CUserIDA, &CLSID_UserIDAObject>, 
public IUserIDA 
{ 
. 
. 
. 
public: 
STDMETHOD(GetSwitchCriteria)(DOUBLE* intensity, DOUBLE* minMass, DOUBLE* maxMass, VARIANT_BOOL *selectIntensity, LONG* numOfDepCycles); 
    . 
    . 
    . 
private: 
    ExploreDataObjects::IFMANWiffFilePtr ipFMANWiffFile; 
ExploreDataObjects::IFMANWiffFile2Ptr ipFMANWiffFile2; 
}; 

を私はこのようなクラスdelcarationのトップにそれらを移動:

class ATL_NO_VTABLE CUserIDA : 
public CComObjectRootEx<CComSingleThreadModel>, 
public CComCoClass<CUserIDA, &CLSID_UserIDAObject>, 
public IUserIDA 
{ 

ExploreDataObjects::IFMANWiffFilePtr ipFMANWiffFile; 
ExploreDataObjects::IFMANWiffFile2Ptr ipFMANWiffFile2; 

私はデフォルトでこれもプライベートメンバーで、前と同じだと思っていたので、なぜこれがうまくいったのか説明するのは迷っています。誰かがこれを説明できますか?

答えて

0

あなたのC++コードは、次の行を除いて、正しいです:

hr = ipFMANFile.CreateInstance(__uuidof(FMANFile)); 

ipFMANFileは、次の文で再び初期化されているので、それは、任意のSENSを作成しません。

残念ながら、このIDL宣言:

IFMANWiffFile* GetWiffFileObject([in] BSTR WiffFileName, [in] long sample); 

は、HRESULTを経由して例外報告用のネイティブCOMのmechanismeをサポートしていないので、デバッグ目的のために限定されています。 COM準拠した宣言は次のようになります。

HRESULT GetWiffFileObject([in] BSTR WiffFileName, [in] long sample, [out, retval] IFMANWiffFile** fileInstance); 

私はあなたがライブラリのコードを変更することができないと信じているので、私はあなたが検査する「procmon.exe」と「dbgview.exe」のようないくつかの外部のデバッグツールを試してみることをお勧めCPPテストケースを実行するとアプリケーションイベントが発生します。失敗したすべてのアクションを探します。

これはあなたに何とか役立つことを望みます。

+0

これらのツールに関するアドバイスをいただきありがとうございます。私は今それらを使用しようとします。 – Travis

関連する問題