我正在使用3. party SDK,它由.dll,.lib和.h文件组成。 我正在使用.dll来对付PInvoke。和.h文件一起查看函数名称和参数。 (所以我没有使用.lib文件)。
SDK相当复杂,因此制作PInvoke包装器已被证明是一项挑战。所有函数/结构/枚举都在.h文件中定义。
我试图包装的函数叫做InitBaseComponent,我可以调用它,但是它返回一个“Error In Argument”枚举。所以我的猜测是编组导致了这个问题。 所以问题是:我这样做了吗?
功能:InitBaseComponent(...)
//C Function: InitBaseComponent(...)
ERROR InitBaseComponent(
Method_Interface* methodInterface, //[in]
void* methodInst, //[in]
ErrorCallBackFunction errorCallbackFunc, //[in]
void* ErrorCallbackInst, //[in]
Component* BaseComponent //[in, out]
);
//C# Function: InitBaseComponent(...)
[DllImport("externalSDK.dll", EntryPoint = "InitBaseComponent", CallingConvention = CallingConvention.Cdecl)]
public static extern ERROR InitBaseComponent(
Method_Interface methodInterface,
IntPtr methodInst,
ErrorCallBackFunction errorCallbackFunc,
IntPtr ErrorCallbackInst,
out Component BaseComponent
);
枚举:错误
//C Enum: ERROR
typedef enum ERROR_E {
OK = 0, //Everything is ok
E_ARG = 1, //Error in the Arguments
E_DATA = 2 //Data error
//And more...
} ERROR;
//C# Enum: ERROR
public enum ERROR
{
OK = 0, //Everything is ok
E_ARG = 1, //Error in the Arguments
E_DATA = 2 //Data error
//And more...
}
结构:Method_Interface
//C struct: Method_Interface
typedef struct Method_Interface_S
{
void* (*Method1)(void* Inst, size_t size);
void* (*Method2)(void* Inst, size_t nelements, size_t bytes);
void* (*Method3)(void* Inst, void *pointer, size_t size);
void (*Method4)(void* Inst, void* pointer);
}Method_Interface;
//C# class: Method_Interface
[StructLayout(LayoutKind.Sequential)]
public class Method_Interface
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void Method1_delegate(IntPtr Inst, uint size);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void Method2_delegate(IntPtr Inst, uint nelements, uint bytes);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void Method3_delegate(IntPtr Inst, IntPtr pointer, uint size);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void Method4_delegate(IntPtr Inst, IntPtr pointer);
public Method1_delegate Method1;
public Method2_delegate Method2;
public Method3_delegate Method3;
public Method4_delegate Method4;
}
委托:ErrorCallBackFunction
//C ErrorCallBackFunction
typedef void (*ErrorCallBackFunction)(void* errorCallBackInst, ERROR errorCode, const char* szMessage, const char* szDetail);
//C# delegate: ErrorCallBackFunction
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ErrorCallBackFunction(IntPtr errorCallBackInst, ERROR errorCode, string szMessage, string szDetail);
结构:组件
//C struct: Component
typedef struct Component_S
{
void* ObjPointer;
unsigned long number;
} Component;
//C# class: Component
[StructLayout(LayoutKind.Sequential)]
public class Component
{
public IntPtr ObjPointer;
public ulong number;
}
任何人都知道我做错了什么?
答案 0 :(得分:3)
您已将C#中的Component
声明为类。这意味着它已经是一个参考。但是你把它作为一个out
参数传递,它增加了一个额外的间接层,一个太多了。因此,您需要删除out
,就像您对methodInterface
所做的那样。
[DllImport(...)]
public static extern ERROR InitBaseComponent(
Method_Interface methodInterface,
IntPtr methodInst,
ErrorCallBackFunction errorCallbackFunc,
IntPtr ErrorCallbackInst,
Component BaseComponent
);
显然,在调用Component
之前,您需要在C#中实例化InitBaseComponent
对象。
其他一些观察结果:
size_t
是指针大小的,因此您在{64}平台上的翻译将失败。uint
是64位,但C ++ long
是32位。所以你对C ++ long
结构的翻译是错误的。必须使用Component
类型声明number
字段。