ホームページ >バックエンド開発 >C++ >C# と C DLL の間で文字列を渡すときに System.AccessViolationException を回避するにはどうすればよいですか?

C# と C DLL の間で文字列を渡すときに System.AccessViolationException を回避するにはどうすればよいですか?

DDD
DDDオリジナル
2025-01-02 19:01:38220ブラウズ

How to Avoid System.AccessViolationException When Passing Strings Between C# and a C   DLL?

C# と C DLL の間での文字列の受け渡し: 最小限の例

問題ステートメント

にもかかわらず一見単純なアプローチに従って、C# と C DLL の間で文字列を渡します。相互運用により System.AccessViolationException が発生します。どちらの言語のコードも正しいように見えますが、問題の根本原因に関して混乱が生じています。

C コード

C コードでは、連結する関数 concat が定義されています。 2 つの文字列を入力し、結果を返します。この関数は、__declspec(dllexport) を使用して DLL にエクスポートするようにマークされています。

extern "C" {
    string concat(string a, string b){
        return a + b;
    }
}

C# コード

C# では、コードは DllImport を使用して concat 関数をインポートします。 CallingConvention は、C の規約に一致するように Cdecl に設定されます。

[DllImport("*****.dll", CallingConvention = CallingConvention.Cdecl)]
static extern string concat(string a, string b);

例外と分析

C# で concat("a", "b") を呼び出すとスローされます。 System.AccessViolationException。この例外は、ネイティブ コード内で無効なメモリ アクセスが発生していることを示します。

解決策: 相互運用互換型

問題の原因は C std の使用にあります。 ::string が相互運用境界を越えます。 C# では、std::string オブジェクトを直接作成したり処理したりすることはできません。代わりに、相互運用互換型をデータ交換に採用する必要があります。

相互運用対応のデータ型

適切な相互運用型には、文字列を渡すための null で終了する文字配列が含まれます。 C# から C へ。 C から C# に文字列を渡す場合、呼び出し側がバッファを割り当て、呼び出し先がバッファに書き込む StringBuilder を使用できます。

修正コード

C では、 concat 関数は、char* および int パラメーターを使用して宣言して、バッファーとそのバッファーを受け取ることができます。

extern "C" {
    void concat(char *str, int len)
    {
        // Concatenate strings and write to buffer
    }
}

C# では、StringBuilder を利用できます。

[DllImport("...", CallingConvention = CallingConvention.Cdecl)]
static extern void concat(StringBuilder str, int len);

....

StringBuilder sb = new StringBuilder(10);
concat(sb, sb.Capacity);

相互運用互換性のある文字列型を使用することにより、C# と C DLL の間の文字列の交換が容易になります。効果的に。

以上がC# と C DLL の間で文字列を渡すときに System.AccessViolationException を回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。