構造体ポインターを介して C# から C に構造体の配列を渡す

オブスリーツー株式会社

C# から C dll に構造体の配列を渡したい。

C での構造体定義:

typedef struct{
    BYTE name[32];
    DWORD age;
}DATA;

次のように構造体をマーシャリングしました。

[StructLayout(LayoutKind.Sequential)]
public struct DATA
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
    public byte[] name;
    public int age;
}

私が伝えたいC関数定義:

void test_data(DATA * pStruct, DWORD length){
    _tprintf("test start\n");
    
    if (!pData)
    {
        _tprintf("pData is NULL\n");
    }
    unsigned int i,j;
    
    for(i = 0; i < length; i++){
        _tprintf("name: ");
        for(j = 0; j < 32; j++){
            _tprintf("%x ",pData[i].name[j]);
        }
        _tprintf("\n");
        _tprintf("age: %d",pData[i].age);
        _tprintf("\n");
    }

    _tprintf("test finish\n");
}

C# の関数シグネチャ:

[DllImport("a.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void test_data(ref DATA pData, int length);

C# でのセットアップ:

int length = 10;
DATA[] arr = new DATA[length];
for(int i = 0; i < length; i++){
  arr[i].name = new byte[32];
  arr[i].age = 10;
}

test_data(ref arr[0], length);

しかし、私はこれらの出力を得ました:

test start
name: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
age: 10
name: 7c 67 9a 2 a 0 0 0 1 0 0 0 2 0 0 0 eb 9 77 67 a4 eb 8f 0 0 0 0 0 2 0 0 0
age: 43673448
test finish

最初のものは正しいですが、2番目のものは奇妙に思えます。参照の渡し方やセットアップの仕方に問題があると思います。

ここでSCardTransmit 関数の pinvoke Web から着想を得ました。ここでは、C# のバイト配列を Cbyte *ref rapdu[0]

これを正しく行う方法は?

エティエンヌ・ド・マルテル

これは、構造体の配列をマネージド コードからネイティブ コードにマーシャリングする方法ではありません。

P/Invoke 宣言で:

[DllImport("a.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void test_data(ref DATA pData, int length);

ref DATA pData単一のDATAオブジェクトへのポインターにマーシャリングします。残りの配列が一緒に送信されるという保証はありません。構造体がblittableである場合は機能していた可能性があります。その場合、マーシャリングは単に配列を固定し、そのアドレスをそのまま C 関数に渡す必要があるためです。しかし、残念なことに、構造体には参照型である配列が含まれています。これを C 関数に渡すと、マーシャラーはコピーを実行して、正しいレイアウトの構造体を取得する必要があります。したがって、 を渡すと、コピーが 1 つだけ送信され、C コードがバッファの最後からすぐに移動し、未定義の動作に遭遇します。また、より哲学的なレベルでは、配列であると想定されていることもあまり明確ではありません。ref arr[0]pData

代わりに、バッチ全体を送信するには、ドキュメントで説明されているように、引数を配列として宣言するだけで、マーシャラーが残りを行います。

[DllImport("a.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void test_data(DATA[] pData, int length);

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

構造体配列ポインターをc#からc ++に渡す

構造体配列ポインターをc#からc ++に渡す

Goから構造体と構造体の配列をC関数に渡す

IntPtrを使用してC#からC ++に構造体の配列を渡す

CからGolangに構造体の配列を渡す

構造体の配列をC ++からGOに渡す

CのDart_NativeArguments構造体から構造体へのポインターを取得します

Cの関数からポインタ構造体配列を返す方法

C構造体に他の構造体の配列へのポインターを含めることはできますか(長さが異なります)

C ++は、配列内のターゲット構造体を含む構造体へのポインターから値を読み取ります

構造体の配列をポインターとして関数に渡す(C)

Cを使用して、データベースから構造体のポインタ変数の配列に文字列を割り当てて読み取る方法

c#からc ++への構造体の配列を含む構造体の受け渡し

cgo:cから構造体配列を渡す方法

配列(ポインタではない)をcの構造体に渡す

その配列へのポインタを使用して、構造体の配列に含まれる構造体のフィールドにアクセスするにはどうすればよいですか?[C ++]

Cのextern構造体からNULLを返すポインタ

C#は、特定の構造体メンバー値に基づいて配列から構造体を取得します

cの構造体へのポインタの配列をパラメータとして渡す方法

Cでファイルから読み取るときに、ポインターを使用して構造体の配列を埋める方法

C-関数からダブルポインタを返す前に、2D配列内の構造体を初期化しています

構造体のポインタ配列にある構造体をcの別の構造体に直接コピーするにはどうすればよいですか?

ctypesを使用してCからPythonに構造体を渡す

C構造体/構造体の配列へのポインタの配列を宣言します

Cでは、構造体または構造体へのポインターを返すかどうかをどのように選択しますか?

Cの構造体へのポインタの配列から情報を取得する

構造体の配列をC ++ dllからC#に返す方法

Cの構造体に文字列と配列を渡す

C#からCコードに渡される構造体の配列

TOP 一覧

  1. 1

    セレンのモデルダイアログからテキストを抽出するにはどうすればよいですか?

  2. 2

    CSSのみを使用して三角形のアニメーションを作成する方法

  3. 3

    ZScalerと証明書の問題により、Dockerを使用できません

  4. 4

    ドロップダウンリストで選択したアイテムのQComboBoxスタイル

  5. 5

    別のホストからTomcat Managerアプリにアクセスする

  6. 6

    PyCharmリモートインタープリターはプロジェクトタブにサイトパッケージのコンテンツを表示しません

  7. 7

    Windows 10でのUSB入力デバイスの挿入/取り外しの検出

  8. 8

    Python / SciPyのピーク検出アルゴリズム

  9. 9

    MLでのデータ前処理の背後にある直感

  10. 10

    useRefに反応してコンポーネントをスクロールして表示する

  11. 11

    モーダルダイアログを自動的に閉じる-サーバーコードが完了したら、Googleスプレッドシートのダイアログを閉じます

  12. 12

    パンダは異なる名前の列に追加します

  13. 13

    PictureBoxで画像のブレンドを無効にする

  14. 14

    Windows 10 Pro 1709を1803、1809、または1903に更新しますか?

  15. 15

    Pythonを使用して、リストからデータを読み取り、特定の値をElasticsearchにインデックス付けするにはどうすればよいですか?

  16. 16

    LinuxでPySide2(Qt for Python)をインストールするQt Designerはどこにありますか?

  17. 17

    Material-UIでTextFieldエラーの色を条件付きでオーバーライドする方法

  18. 18

    goormIDEは、ターミナルがロードするデフォルトプロジェクトを変更します

  19. 19

    MatplotlibまたはSeabornを使用して、グループ化されたデータから複数のプロットを生成するにはどうすればよいですか?

  20. 20

    Luaの文字列から特定の特殊文字を削除するにはどうすればよいですか?

  21. 21

    Flutterにファイルピッカープラグインを追加するにはどうすればよいですか?

ホットタグ

アーカイブ