0

ネイティブ (C) ライブラリの C# ラッパーに取り組んでいます。ネイティブ ライブラリに次の関数プロトタイプがあります。

typedef struct _NativeObj *       NativeObj;
typedef struct AnotherNativeObj * AnotherNative;

__declspec(dllimport) NativeObj createNativeObj (
    AnotherNative * anotherNative,
    FirstCallback   firstCallback,
    void *          firstOpaque,
    SecondCallback  secondCallback,
    void *          secondOpaque,
    ThirdCallback   thirdCallback,
    void *          thirdOpaque,
    const char *    firstString,
    const char *    secondString,
    const char *    thirdString,
    time_t          timeout,
    char *          fourthString,
    int             firstInt,
    int             secondInt,
    int             thirdInt,
    int             fourthInt,
    char *          fifthString,
    int             fifthInt,
    char *          sixthString);

これは、C# コードでの宣言です。

public delegate int ThirdCallbackDelegate(...);

public const uint NO_TIMEOUT = 0;

private uint   timeout   = NO_TIMEOUT;
private string fourthString;
private uint   firstInt  = 0;
private bool   secondInt = false;
private bool   thirdInt  = true;
private bool   fourthInt = true;
private string fifthString;
private bool   fifthInt  = false;
public string  sixthString { get; set; }

[DllImport("path\\to.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern IntPtr createNativeObj(
    IntPtr                 anotherNative,
    FirstCallbackDelegate  firstCallback,
    IntPtr                 firstOpaque,
    SecondCallbackDelegate secondCallback,
    IntPtr                 secondOpaque,
    ThirdCallbackDelegate  thirdCallback,
    IntPtr                 thirdOpaque,
    string                 firstString,
    string                 secondString,
    string                 thirdString,
    int                    timeout,
    string                 fourthString,
    int                    firstInt,
    int                    secondInt,
    int                    thirdInt,
    int                    fourthInt,
    string                 fifthString,
    int                    fifthInt,
    string                 sixthString);

パラメータの背後にあるロジック:

IntPtr myOpaque = createNativeObj(IntPtr.Zero,
            null,
            IntPtr.Zero,
            null,
            IntPtr.Zero,
            thirdCallbackDelegate,
            IntPtr.Zero,
            firstString,
            secondString,
            thirdString,
            (int)timeout,
            fourthString,
            (int)firstInt,
            Convert.ToInt32(secondInt),
            Convert.ToInt32(thirdInt),
            Convert.ToInt32(fourthInt),
            fifthString,
            Convert.ToInt32(fifthInt),
            sixthString);

実行時、ネイティブ関数の開始時に、タイムアウト後の引数の値が壊れています。

4

2 に答える 2

1

Windows では、MS ツールを使用し、 を定義していないと仮定する_USE_32BIT_TIME_Tと、time_t型は 8 バイト幅です。longつまり、一致するように C# p/invoke コードのように宣言する必要があります。

于 2013-10-13T14:49:30.113 に答える
0

あなたのネイティブ ライブラリは __cdecl 呼び出し規約ではなく、__stdcall のようなものを使用していると思われます。一般的には、コンパイラやプロジェクト オプションに決定させるのではなく、ネイティブ ライブラリ レベルで呼び出し規約を適用することをお勧めします。これを試して:

[DllImport("path\\to.dll", CallingConvention=CallingConvention.StdCall)]
于 2013-10-13T12:02:27.297 に答える