简体   繁体   English

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

[英]Last arguments appear corrupted when calling native function

Working on a C# wrapper for a native (C) library. 使用本机(C)库的C#包装器。 I have the following function prototype in the native library: 我在本机库中具有以下函数原型:

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

This is the declaration in the C# code: 这是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);

And the logic behind the parameters: 参数背后的逻辑:

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

At runtime, right at the native function's start, the values for the arguments after timeout are corrupted. 在运行时,就在本机函数开始时,超时后参数的值已损坏。

On Windows, using MS tools, and assuming that you did not define _USE_32BIT_TIME_T , the time_t type is 8 bytes wide. 在Windows上,使用MS工具,并假设您未定义_USE_32BIT_TIME_T ,则time_t类型为8字节宽。 Which means you need to declare it as long in your C# p/invoke code to match. 这意味着你需要以声明它long在你的C#的P / Invoke的代码相匹配。

I suspect that your native library isn't using the __cdecl calling convention but something like __stdcall. 我怀疑您的本机库未使用__cdecl调用约定,而是使用__stdcall之类的东西。 In general it's best to not take any chances and enforce a calling convention at the native library level instead of letting the compiler or the project options determine it. 通常,最好不要冒险,并在本机库级别上强制执行调用约定,而不要让编译器或项目选项来确定它。 Try this: 尝试这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM