2

現在、C# から C で作成されたメソッドを呼び出そうとしています。

C コードは次のようになります。

extern "C"  int addSum(int a, int b)
{
    return a*b;
}

extern "C" int getCount()
{
    return 12;
}

C# コードは次のようになります。

 [DllImport("mydll.dll", SetLastError=true)]
 private static extern int addSum(IntPtr a, IntPtr b);
 [DllImport("mydll.dll", SetLastError = true)]
 private static extern int getCount();

 public static int mySum(int a, int b)
 {
     return suma(a, b);
 }

 public static int getMyCount()
 {
     return getCount();
 }

コードは正しい値を返しますが、次のエラーが発生します。

addSum' がスタックのバランスを崩しました。これは、マネージド PInvoke 署名がアンマネージド ターゲット シグネチャと一致しないことが原因である可能性があります。PInvoke シグネチャの呼び出し規約とパラメーターがターゲットのアンマネージド シグネチャと一致することを確認します。

この問題に関する提案はありますか?

ありがとう

4

2 に答える 2

4

IntPtr を引数として使用する必要はありません。メソッドのシグネチャを定義するときに、整数値を直接使用できます。

[DllImport("mydll.dll", SetLastError = true)]
public static extern int addSum(int a, int b);

[DllImport("mydll.dll", SetLastError = true)]
public static extern int getCount();

次に、関数を直接呼び出します。

int result = SomeClass.addSum(3, 4);
int count = SomeClass.getCount();
于 2011-01-08T09:48:14.890 に答える
4

ターゲット プラットフォームに応じて問題になる場合とそうでない場合があるデータ型に加えて、呼び出し規約も確認する必要がある場合があります。スタックのクリーンアップや、引数がスタックにプッシュされる順序やレジスタに割り当てられる順序などを決定するのは、呼び出し規約です。

C コードでcdecl呼び出し規約を使用するのは一般的です。

[DllImport("mydll.dll", 
           SetLastError=true, 
           CallingConvention=CallingConvention.Cdecl)]
于 2011-01-08T10:01:15.293 に答える