调用本机函数时,最后的参数显示为已损坏

时间:2013-10-13 11:50:00

标签: c# c pinvoke dllimport

使用本机(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);

在运行时,在本机函数的启动时,超时后的参数值已损坏。

2 个答案:

答案 0 :(得分:1)

在Windows上,使用MS工具,假设您没有定义_USE_32BIT_TIME_Ttime_t类型的宽度为8个字节。这意味着您需要在C#p / invoke代码中将其声明为long以匹配。

答案 1 :(得分:0)

我怀疑你的本地库没有使用__cdecl调用约定,而是像__stdcall。通常,最好不要在本机库级别采取任何机会并强制执行调用约定,而不是让编译器或项目选项确定它。试试这个:

[DllImport("path\\to.dll", CallingConvention=CallingConvention.StdCall)]