1

ac#アプリ内のc++dllで関数を呼び出す際に問題が発生しました。私は次のようにc#内で関数を呼び出しています:

[DllImport("cryptopp.dll")]
public static extern IntPtr RSAEncryptString(string filename, string seed, string message);

以下に示すように、c++dllにエクスポートされています。

extern "C" __declspec(dllexport) const char* __cdecl RSAEncryptString(const char *pubFilename, const char *seed, const char *message);

ただし、これを呼び出そうとすると、「外部コンポーネントが例外をスローしました」というメッセージが表示されます。例外。これはまったく説明的ではなく、非常に役に立たないものです。

エクスポートビューアでdllをプルアップすると、完全に定量化された宣言(IE public:void __cdecl CryptoPP :: X509PublicKey :: `vbase destructor'(void)__ptr64)を含む他のすべてのエクスポートされた関数が表示されます。呼び出し、関数名RSAEncryptStringを表示するだけです。

これは、c#側で無効な宣言を使用して関数を誤って呼び出す以外に、私が見ることができる唯一の問題です。System.Runtime.InteropServices.Marshalを間違って使用していますか?

<3を助けてくださいそして前もって感謝します。

4

2 に答える 2

3

最初の行を次のように変更する必要があると思います。

[DllImport("cryptopp.dll",
    CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

非常にわかりやすいものにしたい場合は、次を追加することもできます。

public static extern IntPtr RSAEncryptString(
    [In, MarshalAs(UnmanagedType.LPStr)] string filename,
    [In, MarshalAs(UnmanagedType.LPStr)] string seed,
    [In, MarshalAs(UnmanagedType.LPStr)] string message);

IIRCCharSetは、エンコーディングの処理を行う必要があると考えていますが、そうでない場合は、MarshalAs上記のように、も使用してください。


編集:

ああ、私はあなたがまだエラーを受け取る理由を理解したと思います!コードにはまだ上記の問題がありますがstring、管理対象オブジェクトではないためオブジェクトを返すことができないため、まだエラーが発生しています。IntPtr(のような)ポインタを返し、Marshal.PtrToStringAnsi!を使用する必要があります。

(最初にこれに答えるとき、私はあなたのリターンタイプを実際には見ませんでした。)

于 2011-01-19T15:37:14.907 に答える
0

const char *タイプ(an LPCSTR)の戻り値をタイプIntPtr(通常はHANDLEsではなくsに使用されます)に格納しようとしているようです。これをLPSTR試してください。

[DllImport("cryptopp.dll", CharSet = CharSet.Auto)]
public static extern String RSAEncryptString(String filename, String seed, String message);

また、引数が書き込まれる場合は、outその型の前に追加する必要があることにも注意してください。..., out String message)

于 2011-01-19T16:00:47.013 に答える