1

C++ dll での P/Invoke 呼び出しに問題があります。「エントリ ポイントが見つかりません」というエラーが表示されます。

C ++では、関数を次のように公開しています...

#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllexport)
long
WINAPI
MgScSCardUIDlgSelectCardW(__inout LPOPENCARDNAMEW_EX pOcne);

#ifdef __cplusplus
}
#endif

C# の dllimport ステートメントは次のとおりです。

[DllImport("mgsc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public static extern Int32 MgScSCardUIDlgSelectCardW([MarshalAs(UnmanagedType.Struct)] [In, Out] ModWinsCard.OPENCARDNAME_EX ocnwex);

呼び出し規約、標準、および winapi 呼び出し規約なしでこれを試しました。全員で同じ結果。公開された関数を DependencyWalker で調べたところ、"_MgScSCardUIDlgSelectCardW@4" として公開されていることがわかりました。装飾が正常であることは理解していますが(ただし、「extern "C"」の宣言はそれを処理するはずでした??)が、dllimport がこのように見える関数を持っているサンプル コードを見たことがないので、そうではないようですそれが私がそれを呼ぶべき方法です。

here で .def ファイルを推奨する回答を見てきましたが、これを行う必要があるときに、これは私が学び、台無しにするもう 1 つのことなので、それに対処する必要はありません。

4

1 に答える 1

1

DLL ではすべてが正常です。コンパイラによって名前に追加された @4 接尾辞の利点が得られます。関数に渡される引数値のサイズ (構造体ポインターの場合は 4 バイト) を記述します。これにより、クライアント コード内の関数の宣言の誤りが検出されます。このような不一致は、スタックのバランスを崩すため、トラブルシューティングが非常に困難になる可能性があります。

ここでもうまく機能します。関数が間違っていると宣言したことはほぼ確実です。OPENCARDNAME_EX をクラスではなく構造体として宣言した確率は 99% です。これには、値ではなく参照によって引数を渡す必要があります。[MarshalAs] 属性も間違っています。修理:

[DllImport("mgsc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 MgScSCardUIDlgSelectCardW(ref ModWinsCard.OPENCARDNAME_EX ocnwex);
于 2012-09-26T16:27:25.723 に答える