0

DLL エクスポート ビューアーを使用して、この DLL に含まれる関数を見つけようとしました。関数のリストを見つけました。次のとおりです。

public: int __thiscall CSTVdsDisk::GetPartitionCount(void);

質問はC#にあります。次のいずれかを使用して関数を呼び出すことができません。

[DllImport("Some.dll", 
           ExactSpelling = true,
           EntryPoint = "GetPartitionCount",
           CallingConvention = CallingConvention.StdCall,
           SetLastError = true)]

また:

[DllImport("Some.dll", 
           ExactSpelling = true,
           EntryPoint = "CSTVdsDisk::GetPartitionCount",
           CallingConvention = CallingConvention.StdCall,
           SetLastError = true)]
private static extern int GetPartitionSize();

それらはすべて失敗します。私が間違っていることはありますか?誰でも助けることができますか?ありがとう!

4

3 に答える 3

2

P/Invoke を使用してその関数を呼び出すことはできません。__thiscall呼び出し参照は、この関数がクラス メンバー関数であることを意味しますCSTVdsDiskクラスのメンバー関数です。

関数を呼び出せるようにするには、CSTVdsDiskクラスのインスタンスを作成し、GetPartitionCountそのインスタンスから呼び出す必要があります。

C# では C++ クラスを作成できないため、C++ または C++/CLR でそれを行う必要があります。c# でアンマネージ c++ オブジェクトを作成するも参照してください。

于 2012-06-21T23:47:13.787 に答える
1

名前からして、C++ クラスのメソッドのようです。これにより、次の 2 つの理由から、そのメソッドを P/Invoke から直接呼び出すことが非常に難しくなります。

  1. 「本当の」名前を見つける必要があります。エクスポート ビューアーは、マングルされていない名前を表示しているように見えますが、実際の C++ 関数名は、似ている@0GetPartitionCount@CSTVdsDisk@@QPBAEXAか似ているかのように、はるかに見苦しく見えます。dumpbinその名前を見つけるには、低レベルのツールを使用する必要がある場合があります。
  2. 「thiscall」スタイルの呼び出しを偽造する必要があります。これは、 C++ クラスのインスタンスを最初のパラメーターとして渡す必要があることを意味します。これは、C++ クラス コンストラクターも DLL から公開されている場合にのみ機能します。その場合、クラス コンストラクターを呼び出して、結果を IntPtr に格納し、それを後続のすべての呼び出しに渡すことができます。(コンストラクターが DLL エクスポートとして公開されている場合、マングルされた名前は??`??0CSTVdsDisk@@QAE@ABV0@@Z のように で始まります

この CodeProject の記事では、そのほとんどを行う方法を示していますが、かなり壊れやすいので、問題が発生することを想定してください。同様のことを行う C++ 以外のライブラリ、または少なくとも C コードから使用できるように設計されたライブラリを探すことを強くお勧めします。

于 2012-06-21T23:52:17.510 に答える
0

ネイティブ コードで、関数をエクスポートしていることを確認します。デフォルトでは、関数はエクスポートテーブルにリストされないため、コンパイラがエクスポートすることを認識できるようにマークする必要があります。また、コンパイラが名前を台無しにしないように、関数を extern "C" としてマークする必要があります。

通常、次のマクロを定義します。

#define DLLEXPORT extern "C" __declspec(dllexport)

これらすべてを処理し、エクスポートされた関数を次のように宣言するだけです。

 DLLEXPORT __cdecl int Example(int x, int y)

名前にまだ問題がある場合は、dll で無料の PE エクスプローラー プログラムを使用し、エクスポートされた関数テーブルで正しい名前を確認してください。

于 2012-06-21T23:32:26.477 に答える