1

私はこのCコードを持っています:

real_T addition(const struct_T parameters)
{
    return parameters.a + parameters.b;
}

typedef struct
{
    real_T a;
    real_T b;
} struct_T;

typedef double real_T;

私は次のようにC#から呼び出します:

using System.Runtime.InteropServices;

    namespace AdditionConsoleApplication
    {
        class Program
        {
            [DllImport(@"X:\Bla\Addition.dll", CallingConvention = CallingConvention.Cdecl)]
            public static extern double addition(struct_T parameters);

            static void Main(string[] args)
            {
                struct_T parameters = new struct_T();
                parameters.a = 1;
                parameters.b = 3;

                Console.WriteLine(addition(parameters));
            }
        }
    }

ここでstruct_T:

[StructLayout(LayoutKind.Sequential)]
class struct_T
{
    public double a;
    public double b;
}

残念ながら、数学は正しくありません。

2.72645911468311E-284

誰かが何か間違っているのを見ることができますか?

4

1 に答える 1

1

構造には次の定義があります。

[StructLayout(LayoutKind.Sequential)]
class struct_T
{
    public double a;
    public double b;
}

p / invokeマーシャラーは、参照によってクラスをマーシャリングします。つまり、オブジェクトへのポインタがネイティブコードに渡されます。この不一致は、プログラムが失敗する理由を説明しています。

解決策は、インターフェイスの両側が一致していることを確認することです。1つの方法は、両側で値を渡すことです。これを実現する簡単な方法は、構造体をC#の値型として宣言することです。それを構造体にすることによってそれを行います:

[StructLayout(LayoutKind.Sequential)]
struct struct_T
{
    public double a;
    public double b;
}

もう1つの方法は、両側で参照を渡すことです。classこれは、C#側で使用し、Cコードを変更することで実現できます。

real_T addition(const struct_T* parameters)
{
    return parameters->a + parameters->b;
}
于 2012-12-04T15:57:47.780 に答える