使用本机(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);
在运行时,在本机函数的启动时,超时后的参数值已损坏。
答案 0 :(得分:1)
在Windows上,使用MS工具,假设您没有定义_USE_32BIT_TIME_T
,time_t
类型的宽度为8个字节。这意味着您需要在C#p / invoke代码中将其声明为long
以匹配。
答案 1 :(得分:0)
我怀疑你的本地库没有使用__cdecl调用约定,而是像__stdcall。通常,最好不要在本机库级别采取任何机会并强制执行调用约定,而不是让编译器或项目选项确定它。试试这个:
[DllImport("path\\to.dll", CallingConvention=CallingConvention.StdCall)]