C# 调用本机函数时,最后一个参数似乎已损坏

C# 调用本机函数时,最后一个参数似乎已损坏,c#,c,pinvoke,dllimport,C#,C,Pinvoke,Dllimport,正在为本机(C)库编写C#包装器。我在本机库中有以下函数原型: typedef struct _NativeObj * NativeObj; typedef struct AnotherNativeObj * AnotherNative; __declspec(dllimport) NativeObj createNativeObj ( AnotherNative * anotherNative, FirstCallback firstCallback,

正在为本机(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代码中的声明:

以及参数背后的逻辑:

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);

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

我怀疑您的本机库使用的不是u cdecl调用约定,而是类似于u stdcall的东西。一般来说,最好不要冒险,在本机库级别强制执行调用约定,而不是由编译器或项目选项决定。试试这个:

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

在Windows上,使用MS工具,并假设您没有定义
\u USE\u 32BIT\u TIME\u T
,则
TIME\u T
类型的宽度为8字节。这意味着您需要在C#p/调用代码中将其声明为
long
以进行匹配。

为什么不使用StringBuilder而不是String?如果您的意思是,对于fifthString和sixthString,它们实际上是const char*类型。我正试图纠正这一点,但我公司的DLP解决方案让我很难编辑这个问题……似乎我宣布
time\t
错了。在我们的代码中,typedef是
long
。这没有帮助,我现在看到不止一对被错误地传递了。@Oliver如果本机函数是
\uu stdcall
,它将被声明为这样。本机代码中缺少调用约定意味着它是
\uuu cdecl
。谢谢,在这种情况下,它实际上在某些头文件中显式地
typedef
。呃,如果您的时间是您自己的类型,那么我们可以为您提供的帮助就不多了。除非我们能就这些类型达成一致,否则你只能靠自己了。
[DllImport("path\\to.dll", CallingConvention=CallingConvention.StdCall)]